pptx-react-viewer 1.16.2 → 1.17.1
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 +16 -0
- package/dist/{Model3DScene-DI6FSWDL.mjs → Model3DScene-QHDYQXL2.mjs} +2 -2
- package/dist/Model3DScene-QHDYQXL2.mjs.br +0 -0
- package/dist/Model3DScene-QHDYQXL2.mjs.gz +0 -0
- package/dist/{Model3DScene-PE7L24QK.js → Model3DScene-YA4F63DT.js} +3 -3
- package/dist/Model3DScene-YA4F63DT.js.br +0 -0
- package/dist/Model3DScene-YA4F63DT.js.gz +0 -0
- package/dist/PowerPointViewer-C4d7SKZf.d.ts +21 -0
- package/dist/PowerPointViewer-C4d7SKZf.d.ts.map +1 -0
- package/dist/{SurfaceChart3DScene-NMLG3BQK.mjs → SurfaceChart3DScene-GUAS2NWQ.mjs} +2 -2
- package/dist/SurfaceChart3DScene-GUAS2NWQ.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-GUAS2NWQ.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-AJLD3VW6.js → SurfaceChart3DScene-TGNJHTJQ.js} +3 -3
- package/dist/SurfaceChart3DScene-TGNJHTJQ.js.br +0 -0
- package/dist/SurfaceChart3DScene-TGNJHTJQ.js.gz +0 -0
- package/dist/{chunk-HJQZJ3VE.mjs → chunk-5CD34U2V.mjs} +1 -1
- package/dist/chunk-5CD34U2V.mjs.br +0 -0
- package/dist/chunk-5CD34U2V.mjs.gz +0 -0
- package/dist/{chunk-46HNHBHF.mjs → chunk-G22EWPLH.mjs} +134 -4
- package/dist/chunk-G22EWPLH.mjs.br +0 -0
- package/dist/chunk-G22EWPLH.mjs.gz +0 -0
- package/dist/{chunk-JBCVQFWI.mjs → chunk-HN7CPQUG.mjs} +5 -5
- package/dist/chunk-HN7CPQUG.mjs.br +0 -0
- package/dist/chunk-HN7CPQUG.mjs.gz +0 -0
- package/dist/{chunk-WGLJ32FW.js → chunk-IZXN663G.js} +1 -1
- package/dist/chunk-IZXN663G.js.br +0 -0
- package/dist/chunk-IZXN663G.js.gz +0 -0
- package/dist/{chunk-WMRS37KQ.js → chunk-JWS3RQKN.js} +160 -28
- package/dist/chunk-JWS3RQKN.js.br +0 -0
- package/dist/chunk-JWS3RQKN.js.gz +0 -0
- package/dist/{chunk-YAQOTVZT.js → chunk-MGLRKGCH.js} +146 -66
- package/dist/chunk-MGLRKGCH.js.br +0 -0
- package/dist/chunk-MGLRKGCH.js.gz +0 -0
- package/dist/{chunk-DZF4BNRP.mjs → chunk-PCQH2UBR.mjs} +230 -232
- package/dist/chunk-PCQH2UBR.mjs.br +0 -0
- package/dist/chunk-PCQH2UBR.mjs.gz +0 -0
- package/dist/{chunk-MZYQUURK.js → chunk-SXCO5HHN.js} +438 -438
- package/dist/chunk-SXCO5HHN.js.br +0 -0
- package/dist/chunk-SXCO5HHN.js.gz +0 -0
- package/dist/{chunk-VRASDGWX.js → chunk-WH7YXV3I.js} +1026 -1028
- package/dist/chunk-WH7YXV3I.js.br +0 -0
- package/dist/chunk-WH7YXV3I.js.gz +0 -0
- package/dist/{chunk-X7ILBQEY.mjs → chunk-XRYREYXC.mjs} +146 -66
- package/dist/chunk-XRYREYXC.mjs.br +0 -0
- package/dist/chunk-XRYREYXC.mjs.gz +0 -0
- package/dist/{dist-VMFNUFUX.js → dist-2ZAH7U6U.js} +507 -507
- package/dist/dist-2ZAH7U6U.js.br +0 -0
- package/dist/dist-2ZAH7U6U.js.gz +0 -0
- package/dist/{dist-JJ2NI2O3.mjs → dist-MXDC6YTS.mjs} +1 -1
- package/dist/dist-MXDC6YTS.mjs.br +0 -0
- package/dist/dist-MXDC6YTS.mjs.gz +0 -0
- package/dist/hooks-unstable.d.ts +9683 -1886
- package/dist/hooks-unstable.d.ts.map +1 -0
- package/dist/hooks-unstable.js +75 -75
- package/dist/hooks-unstable.js.br +0 -0
- package/dist/hooks-unstable.js.gz +0 -0
- package/dist/hooks-unstable.mjs +4 -4
- package/dist/hooks-unstable.mjs.br +0 -0
- package/dist/hooks-unstable.mjs.gz +0 -0
- package/dist/i18n.d.ts +27 -1
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +3 -3
- package/dist/i18n.js.br +1 -1
- package/dist/i18n.js.gz +0 -0
- package/dist/i18n.mjs +1 -1
- package/dist/i18n.mjs.br +0 -0
- package/dist/i18n.mjs.gz +0 -0
- package/dist/index-XGt7MZpa.d.ts +607 -0
- package/dist/index-XGt7MZpa.d.ts.map +1 -0
- package/dist/index.d.ts +4753 -10
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -19
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/types-BK7Nt13M.d.ts +483 -0
- package/dist/types-BK7Nt13M.d.ts.map +1 -0
- package/dist/viewer/index.d.ts +8008 -88
- package/dist/viewer/index.d.ts.map +1 -0
- package/dist/viewer/index.js +20 -20
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +5 -5
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +6 -5
- package/dist/Model3DScene-DI6FSWDL.mjs.br +0 -0
- package/dist/Model3DScene-DI6FSWDL.mjs.gz +0 -0
- package/dist/Model3DScene-PE7L24QK.js.br +0 -0
- package/dist/Model3DScene-PE7L24QK.js.gz +0 -0
- package/dist/PowerPointViewer-BsaUH3ZT.d.ts +0 -26
- package/dist/PowerPointViewer-Nxku67uL.d.mts +0 -26
- package/dist/SurfaceChart3DScene-AJLD3VW6.js.br +0 -0
- package/dist/SurfaceChart3DScene-AJLD3VW6.js.gz +0 -0
- package/dist/SurfaceChart3DScene-NMLG3BQK.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-NMLG3BQK.mjs.gz +0 -0
- package/dist/chunk-46HNHBHF.mjs.br +0 -0
- package/dist/chunk-46HNHBHF.mjs.gz +0 -0
- package/dist/chunk-DZF4BNRP.mjs.br +0 -0
- package/dist/chunk-DZF4BNRP.mjs.gz +0 -0
- package/dist/chunk-HJQZJ3VE.mjs.br +0 -0
- package/dist/chunk-HJQZJ3VE.mjs.gz +0 -0
- package/dist/chunk-JBCVQFWI.mjs.br +0 -0
- package/dist/chunk-JBCVQFWI.mjs.gz +0 -0
- package/dist/chunk-MZYQUURK.js.br +0 -0
- package/dist/chunk-MZYQUURK.js.gz +0 -0
- package/dist/chunk-VRASDGWX.js.br +0 -0
- package/dist/chunk-VRASDGWX.js.gz +0 -0
- package/dist/chunk-WGLJ32FW.js.br +0 -0
- package/dist/chunk-WGLJ32FW.js.gz +0 -0
- package/dist/chunk-WMRS37KQ.js.br +0 -0
- package/dist/chunk-WMRS37KQ.js.gz +0 -0
- package/dist/chunk-X7ILBQEY.mjs.br +0 -0
- package/dist/chunk-X7ILBQEY.mjs.gz +0 -0
- package/dist/chunk-YAQOTVZT.js.br +0 -0
- package/dist/chunk-YAQOTVZT.js.gz +0 -0
- package/dist/dist-JJ2NI2O3.mjs.br +0 -0
- package/dist/dist-JJ2NI2O3.mjs.gz +0 -0
- package/dist/dist-VMFNUFUX.js.br +0 -0
- package/dist/dist-VMFNUFUX.js.gz +0 -0
- package/dist/hooks-unstable.d.mts +0 -2300
- package/dist/i18n.d.mts +0 -1
- package/dist/index.d.mts +0 -46
- package/dist/types-ui-NG29h55h.d.mts +0 -712
- package/dist/types-ui-NG29h55h.d.ts +0 -712
- package/dist/usePresenterWindow-DToCijGy.d.ts +0 -1619
- package/dist/usePresenterWindow-DeTm-unp.d.mts +0 -1619
- package/dist/viewer/index.d.mts +0 -129
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,4601 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import react__default from 'react';
|
|
3
3
|
import { Options } from 'html2canvas-pro';
|
|
4
|
-
import * as React$1 from 'react';
|
|
5
|
-
import { ViewerTheme } from './theme/index.js';
|
|
6
|
-
export { ViewerTheme, ViewerThemeColors, defaultCssVars, defaultRadius, defaultThemeColors, themeToCssVars, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius } from './theme/index.js';
|
|
7
|
-
import './presentation-BfnrtJV1.js';
|
|
8
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Theme configuration types for the PowerPoint viewer.
|
|
7
|
+
*
|
|
8
|
+
* All color values accept any valid CSS color string:
|
|
9
|
+
* hex (`#6366f1`), rgb (`rgb(99 102 241)`), hsl (`hsl(239 84% 67%)`),
|
|
10
|
+
* oklch (`oklch(0.585 0.233 277)`), named colors, etc.
|
|
11
|
+
*
|
|
12
|
+
* Framework-agnostic — shared by the React, Vue, and Angular bindings.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Semantic color tokens for the viewer UI.
|
|
16
|
+
*
|
|
17
|
+
* These map to CSS custom properties (`--pptx-<token>`) and drive all
|
|
18
|
+
* UI component colors. The naming follows the shadcn/ui convention so
|
|
19
|
+
* that Tailwind + shadcn users get a familiar experience.
|
|
20
|
+
*/
|
|
21
|
+
interface ViewerThemeColors {
|
|
22
|
+
/** Page / root background */
|
|
23
|
+
background: string;
|
|
24
|
+
/** Default text color */
|
|
25
|
+
foreground: string;
|
|
26
|
+
/** Card / panel surface */
|
|
27
|
+
card: string;
|
|
28
|
+
/** Text on card surfaces */
|
|
29
|
+
cardForeground: string;
|
|
30
|
+
/** Popover / dropdown surface */
|
|
31
|
+
popover: string;
|
|
32
|
+
/** Text inside popovers */
|
|
33
|
+
popoverForeground: string;
|
|
34
|
+
/** Primary action color (buttons, active indicators) */
|
|
35
|
+
primary: string;
|
|
36
|
+
/** Text on primary-colored backgrounds */
|
|
37
|
+
primaryForeground: string;
|
|
38
|
+
/** Secondary / subdued action color */
|
|
39
|
+
secondary: string;
|
|
40
|
+
/** Text on secondary backgrounds */
|
|
41
|
+
secondaryForeground: string;
|
|
42
|
+
/** Muted / disabled surface */
|
|
43
|
+
muted: string;
|
|
44
|
+
/** Text on muted surfaces (also used for secondary text) */
|
|
45
|
+
mutedForeground: string;
|
|
46
|
+
/** Accent / hover-highlight surface */
|
|
47
|
+
accent: string;
|
|
48
|
+
/** Text on accent surfaces */
|
|
49
|
+
accentForeground: string;
|
|
50
|
+
/** Destructive / danger action color */
|
|
51
|
+
destructive: string;
|
|
52
|
+
/** Text on destructive backgrounds */
|
|
53
|
+
destructiveForeground: string;
|
|
54
|
+
/** Default border color */
|
|
55
|
+
border: string;
|
|
56
|
+
/** Input field border color */
|
|
57
|
+
input: string;
|
|
58
|
+
/** Focus ring color */
|
|
59
|
+
ring: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Full viewer theme configuration.
|
|
63
|
+
*
|
|
64
|
+
* Every property is optional — unset values fall back to the built-in
|
|
65
|
+
* dark theme defaults.
|
|
66
|
+
*/
|
|
67
|
+
interface ViewerTheme {
|
|
68
|
+
/** Semantic UI colors. Each key maps to a `--pptx-<key>` CSS custom property. */
|
|
69
|
+
colors?: Partial<ViewerThemeColors>;
|
|
70
|
+
/** Base border-radius value (e.g. `"0.5rem"`, `"8px"`). */
|
|
71
|
+
radius?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Escape hatch: arbitrary CSS custom properties to set on the viewer
|
|
74
|
+
* root element. Keys should include the `--` prefix.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* { "--my-custom-shadow": "0 4px 12px rgba(0,0,0,0.5)" }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
cssVars?: Record<string, string>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Default dark-theme color values.
|
|
86
|
+
*
|
|
87
|
+
* These correspond to the built-in dark UI of the PowerPoint viewer and
|
|
88
|
+
* use Tailwind's gray palette as the neutral scale with indigo as the
|
|
89
|
+
* primary accent.
|
|
90
|
+
*/
|
|
91
|
+
declare const defaultThemeColors: ViewerThemeColors;
|
|
92
|
+
/** Default border-radius. */
|
|
93
|
+
declare const defaultRadius = "0.5rem";
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Convert a `ViewerTheme` into a flat `Record<string, string>` of CSS
|
|
97
|
+
* custom properties (including the `--` prefix) ready to be spread onto
|
|
98
|
+
* a `style` attribute.
|
|
99
|
+
*
|
|
100
|
+
* Only properties that differ from the built-in defaults are emitted when
|
|
101
|
+
* `omitDefaults` is true (the default).
|
|
102
|
+
*/
|
|
103
|
+
declare function themeToCssVars(theme: ViewerTheme | undefined, omitDefaults?: boolean): Record<string, string>;
|
|
104
|
+
/**
|
|
105
|
+
* Build the complete set of CSS custom properties with all defaults.
|
|
106
|
+
* Useful for generating a full fallback stylesheet.
|
|
107
|
+
*/
|
|
108
|
+
declare function defaultCssVars(): Record<string, string>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Built-in "vermilion" theme presets.
|
|
112
|
+
*
|
|
113
|
+
* These mirror the pptx-viewer brand used on the documentation site:
|
|
114
|
+
* a warm paper canvas in light mode, a dimmed presenter room in dark
|
|
115
|
+
* mode, and the vermilion accent in both. Pass one to the viewer's
|
|
116
|
+
* `theme` prop (React/Vue) or `provideViewerTheme` (Angular), or spread
|
|
117
|
+
* the color objects to derive your own variant.
|
|
118
|
+
*/
|
|
119
|
+
/** Light "paper" palette: a projection screen in a bright room. */
|
|
120
|
+
declare const vermilionLightColors: ViewerThemeColors;
|
|
121
|
+
/** Dark "presenter" palette: the presenter room with the lights down. */
|
|
122
|
+
declare const vermilionDarkColors: ViewerThemeColors;
|
|
123
|
+
/** Shared border-radius for the vermilion presets (slightly sharper than the default). */
|
|
124
|
+
declare const vermilionRadius = "0.375rem";
|
|
125
|
+
/** Light vermilion theme, ready for the viewer's `theme` prop. */
|
|
126
|
+
declare const vermilionLightTheme: ViewerTheme;
|
|
127
|
+
/** Dark vermilion theme, ready for the viewer's `theme` prop. */
|
|
128
|
+
declare const vermilionDarkTheme: ViewerTheme;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Action types: hyperlinks, slide jumps, macros, and action buttons.
|
|
132
|
+
*
|
|
133
|
+
* @module pptx-types/actions
|
|
134
|
+
*/
|
|
135
|
+
/**
|
|
136
|
+
* A parsed shape-level action from `a:hlinkClick` or `a:hlinkHover`.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* const link: PptxAction = {
|
|
141
|
+
* url: "https://example.com",
|
|
142
|
+
* tooltip: "Visit Example",
|
|
143
|
+
* highlightClick: true,
|
|
144
|
+
* };
|
|
145
|
+
*
|
|
146
|
+
* const slideJump: PptxAction = {
|
|
147
|
+
* action: "ppaction://hlinksldjump",
|
|
148
|
+
* targetSlideIndex: 3,
|
|
149
|
+
* };
|
|
150
|
+
* // => satisfies PptxAction
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
interface PptxAction {
|
|
154
|
+
/** Relationship ID referencing the action target. */
|
|
155
|
+
rId?: string;
|
|
156
|
+
/** OOXML action string (e.g. `ppaction://hlinksldjump`). */
|
|
157
|
+
action?: string;
|
|
158
|
+
/** Tooltip text shown on hover. */
|
|
159
|
+
tooltip?: string;
|
|
160
|
+
/** Whether the shape should highlight on click. */
|
|
161
|
+
highlightClick?: boolean;
|
|
162
|
+
/** Resolved URL or file path from the slide relationship map. */
|
|
163
|
+
url?: string;
|
|
164
|
+
/** Zero-based index into the slides array for internal slide jumps. */
|
|
165
|
+
targetSlideIndex?: number;
|
|
166
|
+
/** Relationship ID of an optional click sound (`a:snd/@r:embed`). */
|
|
167
|
+
soundRId?: string;
|
|
168
|
+
/** Resolved media target path for the optional click sound. */
|
|
169
|
+
soundPath?: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Shared value types used across the entire PPTX editor type system.
|
|
174
|
+
*
|
|
175
|
+
* Contains primitive enums, small interfaces, and the XML object alias
|
|
176
|
+
* that almost every other type file imports.
|
|
177
|
+
*
|
|
178
|
+
* @module pptx-types/common
|
|
179
|
+
*/
|
|
180
|
+
/**
|
|
181
|
+
* Underline style tokens from OOXML `a:rPr/@u`.
|
|
182
|
+
*
|
|
183
|
+
* These map directly to the OpenXML `ST_TextUnderlineType` simple type.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* const style: UnderlineStyle = "wavy";
|
|
188
|
+
* // => "wavy" — one of: sng | dbl | heavy | dotted | dash | wavy | none | ...
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
type UnderlineStyle = 'sng' | 'dbl' | 'heavy' | 'dotted' | 'dottedHeavy' | 'dash' | 'dashHeavy' | 'dashLong' | 'dashLongHeavy' | 'dotDash' | 'dotDashHeavy' | 'dotDotDash' | 'dotDotDashHeavy' | 'wavy' | 'wavyHeavy' | 'wavyDbl' | 'none';
|
|
192
|
+
/**
|
|
193
|
+
* Connector connection point reference — links a connector endpoint to a
|
|
194
|
+
* specific shape on the slide.
|
|
195
|
+
*
|
|
196
|
+
* When both `shapeId` and `connectionSiteIndex` are set, the connector
|
|
197
|
+
* end snaps to that shapes’s connection site and “follows” the shape when
|
|
198
|
+
* it is moved.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* const start: ConnectorConnectionPoint = {
|
|
203
|
+
* shapeId: "shape_1",
|
|
204
|
+
* connectionSiteIndex: 2,
|
|
205
|
+
* };
|
|
206
|
+
* // => { shapeId: "shape_1", connectionSiteIndex: 2 } satisfies ConnectorConnectionPoint
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
interface ConnectorConnectionPoint {
|
|
210
|
+
/** ID of the shape this connector endpoint is attached to. */
|
|
211
|
+
shapeId?: string;
|
|
212
|
+
/** Connection site index on the target shape (0-based). */
|
|
213
|
+
connectionSiteIndex?: number;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Arrow head types for connector start/end.
|
|
217
|
+
*
|
|
218
|
+
* Maps to `a:headEnd/@type` and `a:tailEnd/@type` in OOXML.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* const arrow: ConnectorArrowType = "triangle";
|
|
223
|
+
* // => "triangle" — one of: none | triangle | stealth | diamond | oval | arrow
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
type ConnectorArrowType = 'none' | 'triangle' | 'stealth' | 'diamond' | 'oval' | 'arrow';
|
|
227
|
+
/**
|
|
228
|
+
* Stroke dash pattern types for lines and shape outlines.
|
|
229
|
+
*
|
|
230
|
+
* Maps to `a:ln/a:prstDash/@val` in OOXML. Use `"custom"` for
|
|
231
|
+
* user-defined dash/space arrays.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* const dash: StrokeDashType = "dashDot";
|
|
236
|
+
* // => "dashDot" — one of: solid | dot | dash | lgDash | dashDot | custom | ...
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
type StrokeDashType = 'solid' | 'dot' | 'dash' | 'lgDash' | 'dashDot' | 'lgDashDot' | 'lgDashDotDot' | 'sysDot' | 'sysDash' | 'sysDashDot' | 'sysDashDotDot' | 'custom';
|
|
240
|
+
/**
|
|
241
|
+
* Shadow effect properties for a single shadow layer.
|
|
242
|
+
*
|
|
243
|
+
* Represents parsed values from an `<a:outerShdw>` node. Multiple instances
|
|
244
|
+
* can be stored in {@link ShapeStyle.shadows} for compound shadow effects.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* const shadow: ShadowEffect = {
|
|
249
|
+
* color: "#000000",
|
|
250
|
+
* opacity: 0.4,
|
|
251
|
+
* blur: 6,
|
|
252
|
+
* angle: 315,
|
|
253
|
+
* distance: 4,
|
|
254
|
+
* };
|
|
255
|
+
* // => { color: "#000000", opacity: 0.4, blur: 6, angle: 315, distance: 4 } satisfies ShadowEffect
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
interface ShadowEffect {
|
|
259
|
+
/** Shadow color as hex string. */
|
|
260
|
+
color: string;
|
|
261
|
+
/** Shadow opacity (0-1). */
|
|
262
|
+
opacity: number;
|
|
263
|
+
/** Blur radius in pixels. */
|
|
264
|
+
blur: number;
|
|
265
|
+
/** Shadow angle in degrees (0-360). */
|
|
266
|
+
angle: number;
|
|
267
|
+
/** Shadow distance in pixels. */
|
|
268
|
+
distance: number;
|
|
269
|
+
/** Whether shadow rotates with shape. */
|
|
270
|
+
rotateWithShape?: boolean;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Strongly-typed parsed XML node from fast-xml-parser.
|
|
274
|
+
*
|
|
275
|
+
* The parser is configured with `attributeNamePrefix: '@_'`,
|
|
276
|
+
* `parseAttributeValue: false`, and `parseTagValue: false`, so attribute and
|
|
277
|
+
* text values are always strings at runtime. This type encodes that:
|
|
278
|
+
*
|
|
279
|
+
* - **Attributes** — keys matching `` `@_${string}` `` return
|
|
280
|
+
* `string | undefined` directly.
|
|
281
|
+
* - **Text content** — `#text` returns `string | undefined`.
|
|
282
|
+
* - **Child elements** — any other string key returns
|
|
283
|
+
* `XmlObject | XmlObject[] | string | undefined`. The union reflects that
|
|
284
|
+
* fast-xml-parser may emit an object (single child), an array (repeated
|
|
285
|
+
* children), or a bare string (text-only element collapsed by the parser).
|
|
286
|
+
*
|
|
287
|
+
* For traversal, prefer the helpers in {@link ./../utils/xml-access} —
|
|
288
|
+
* `xmlChild` / `xmlChildren` / `xmlAttr` / `xmlText` / `xmlPath` — which
|
|
289
|
+
* narrow the union and normalize the single-vs-array duality. Direct
|
|
290
|
+
* indexing works for attributes (typed as string) but chained child access
|
|
291
|
+
* (`obj['p:spPr']?.['a:xfrm']`) requires the helpers or a narrowing cast
|
|
292
|
+
* because TypeScript cannot index into the `XmlObject[] | string` part of
|
|
293
|
+
* the union.
|
|
294
|
+
*/
|
|
295
|
+
interface XmlObject {
|
|
296
|
+
/** Attributes (`@_`-prefixed keys) are always strings at runtime. */
|
|
297
|
+
[attr: `@_${string}`]: string | undefined;
|
|
298
|
+
/** Element text content surfaces under `#text` when present. */
|
|
299
|
+
'#text'?: string;
|
|
300
|
+
/**
|
|
301
|
+
* Child elements keyed by their (namespaced) tag name. fast-xml-parser
|
|
302
|
+
* emits a single object for unique elements, an array for repeated ones,
|
|
303
|
+
* and a bare string for elements collapsed to their text content. Use
|
|
304
|
+
* the helpers in `utils/xml-access` to narrow this union.
|
|
305
|
+
*/
|
|
306
|
+
[child: string]: XmlObject | XmlObject[] | string | undefined;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Shape lock attributes from `p:cNvSpPr / a:spLocks`.
|
|
310
|
+
*
|
|
311
|
+
* When a flag is `true` the corresponding user interaction is disabled
|
|
312
|
+
* in the editor (e.g. `noRotation` prevents free rotation of the shape).
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```ts
|
|
316
|
+
* const locks: PptxShapeLocks = { noMove: true, noResize: true };
|
|
317
|
+
* // => { noMove: true, noResize: true } satisfies PptxShapeLocks
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
interface PptxShapeLocks {
|
|
321
|
+
noGrouping?: boolean;
|
|
322
|
+
noRotation?: boolean;
|
|
323
|
+
noMove?: boolean;
|
|
324
|
+
noResize?: boolean;
|
|
325
|
+
noTextEdit?: boolean;
|
|
326
|
+
noSelect?: boolean;
|
|
327
|
+
noChangeAspect?: boolean;
|
|
328
|
+
noEditPoints?: boolean;
|
|
329
|
+
noAdjustHandles?: boolean;
|
|
330
|
+
noChangeArrowheads?: boolean;
|
|
331
|
+
noChangeShapeType?: boolean;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* A drawing guide parsed from OOXML extension lists.
|
|
335
|
+
*
|
|
336
|
+
* Slide-level and presentation-level guides are shown as thin coloured
|
|
337
|
+
* lines that help users align elements.
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* const guide: PptxDrawingGuide = {
|
|
342
|
+
* id: "g1",
|
|
343
|
+
* orientation: "horz",
|
|
344
|
+
* positionEmu: 457200,
|
|
345
|
+
* color: "#FF0000",
|
|
346
|
+
* };
|
|
347
|
+
* // => { id: "g1", orientation: "horz", positionEmu: 457200, color: "#FF0000" } satisfies PptxDrawingGuide
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
interface PptxDrawingGuide {
|
|
351
|
+
/** Unique identifier (from `@_id` attribute or generated). */
|
|
352
|
+
id: string;
|
|
353
|
+
/** Orientation: horizontal or vertical. */
|
|
354
|
+
orientation: 'horz' | 'vert';
|
|
355
|
+
/** Position in EMU (converted from pos attribute). */
|
|
356
|
+
positionEmu: number;
|
|
357
|
+
/** Optional guide colour as hex string (e.g. "#FF0000"). */
|
|
358
|
+
color?: string;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Geometry types: adjustment handles, custom geometry points, segments,
|
|
363
|
+
* paths, and custom path properties.
|
|
364
|
+
*
|
|
365
|
+
* @module pptx-types/geometry
|
|
366
|
+
*/
|
|
367
|
+
/**
|
|
368
|
+
* Defines an adjustment handle position for a shape geometry.
|
|
369
|
+
*
|
|
370
|
+
* Adjustment handles allow users to interactively reshape preset shapes
|
|
371
|
+
* (e.g. rounding a rectangle corner or adjusting arrow head width).
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```ts
|
|
375
|
+
* const handle: GeometryAdjustmentHandle = {
|
|
376
|
+
* guideName: "adj",
|
|
377
|
+
* xFraction: 0.25,
|
|
378
|
+
* minValue: 0,
|
|
379
|
+
* maxValue: 50000,
|
|
380
|
+
* };
|
|
381
|
+
* // => satisfies GeometryAdjustmentHandle
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
interface GeometryAdjustmentHandle {
|
|
385
|
+
/** Name of the adjustment guide this handle controls (e.g. "adj", "adj1"). */
|
|
386
|
+
guideName: string;
|
|
387
|
+
/** X position as a fraction of shape width (0..1), or undefined if the handle only moves vertically. */
|
|
388
|
+
xFraction?: number;
|
|
389
|
+
/** Y position as a fraction of shape height (0..1), or undefined if the handle only moves horizontally. */
|
|
390
|
+
yFraction?: number;
|
|
391
|
+
/** Minimum allowed value for the adjustment guide. */
|
|
392
|
+
minValue?: number;
|
|
393
|
+
/** Maximum allowed value for the adjustment guide. */
|
|
394
|
+
maxValue?: number;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* A single point in a custom geometry path.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```ts
|
|
401
|
+
* const pt: CustomGeometryPoint = { x: 100, y: 200 };
|
|
402
|
+
* // => satisfies CustomGeometryPoint
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
interface CustomGeometryPoint {
|
|
406
|
+
x: number;
|
|
407
|
+
y: number;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* A segment within a custom geometry path.
|
|
411
|
+
*
|
|
412
|
+
* Discriminated union over `type` — can be a moveTo, lineTo,
|
|
413
|
+
* cubic Bézier, quadratic Bézier, or close command.
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```ts
|
|
417
|
+
* const segments: CustomGeometrySegment[] = [
|
|
418
|
+
* { type: "moveTo", pt: { x: 0, y: 0 } },
|
|
419
|
+
* { type: "lineTo", pt: { x: 100, y: 0 } },
|
|
420
|
+
* { type: "lineTo", pt: { x: 100, y: 100 } },
|
|
421
|
+
* { type: "close" },
|
|
422
|
+
* ];
|
|
423
|
+
* // => satisfies CustomGeometrySegment[]
|
|
424
|
+
* ```
|
|
425
|
+
*/
|
|
426
|
+
type CustomGeometrySegment = {
|
|
427
|
+
type: 'moveTo';
|
|
428
|
+
pt: CustomGeometryPoint;
|
|
429
|
+
} | {
|
|
430
|
+
type: 'lineTo';
|
|
431
|
+
pt: CustomGeometryPoint;
|
|
432
|
+
} | {
|
|
433
|
+
type: 'cubicBezTo';
|
|
434
|
+
pts: [CustomGeometryPoint, CustomGeometryPoint, CustomGeometryPoint];
|
|
435
|
+
} | {
|
|
436
|
+
type: 'quadBezTo';
|
|
437
|
+
pts: [CustomGeometryPoint, CustomGeometryPoint];
|
|
438
|
+
} | {
|
|
439
|
+
type: 'arcTo';
|
|
440
|
+
/** Horizontal radius of the ellipse. */
|
|
441
|
+
wR: number;
|
|
442
|
+
/** Vertical radius of the ellipse. */
|
|
443
|
+
hR: number;
|
|
444
|
+
/** Start angle in 60000ths of a degree. */
|
|
445
|
+
stAng: number;
|
|
446
|
+
/** Sweep angle in 60000ths of a degree. */
|
|
447
|
+
swAng: number;
|
|
448
|
+
} | {
|
|
449
|
+
type: 'close';
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* A single sub-path in a custom geometry definition (maps to one `a:path`).
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* ```ts
|
|
456
|
+
* const path: CustomGeometryPath = {
|
|
457
|
+
* width: 100,
|
|
458
|
+
* height: 100,
|
|
459
|
+
* segments: [
|
|
460
|
+
* { type: "moveTo", pt: { x: 0, y: 0 } },
|
|
461
|
+
* { type: "lineTo", pt: { x: 100, y: 100 } },
|
|
462
|
+
* ],
|
|
463
|
+
* };
|
|
464
|
+
* // => satisfies CustomGeometryPath
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
interface CustomGeometryPath {
|
|
468
|
+
/** Coordinate-space width for this sub-path. */
|
|
469
|
+
width: number;
|
|
470
|
+
/** Coordinate-space height for this sub-path. */
|
|
471
|
+
height: number;
|
|
472
|
+
/** Ordered list of drawing segments. */
|
|
473
|
+
segments: CustomGeometrySegment[];
|
|
474
|
+
/** Path fill mode (`a:path/@fill`): norm, lighten, lightenLess, darken, darkenLess, none. */
|
|
475
|
+
fillMode?: 'norm' | 'lighten' | 'lightenLess' | 'darken' | 'darkenLess' | 'none';
|
|
476
|
+
/** Whether the path is stroked (`a:path/@stroke`). */
|
|
477
|
+
stroke?: boolean;
|
|
478
|
+
/** 3D extrusion compatibility (`a:path/@extrusionOk`). */
|
|
479
|
+
extrusionOk?: boolean;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Auxiliary raw XML preserved from `a:custGeom` for round-trip serialization.
|
|
483
|
+
* These are stored opaquely so adjustment guides, handles, connection sites,
|
|
484
|
+
* and the text rectangle are not lost when a custGeom is edited and saved.
|
|
485
|
+
*/
|
|
486
|
+
interface CustomGeometryRawData {
|
|
487
|
+
/** Raw `a:gdLst` XML content (guide list). */
|
|
488
|
+
gdLstXml?: unknown;
|
|
489
|
+
/** Raw `a:ahLst` XML content (adjustment handles). */
|
|
490
|
+
ahLstXml?: unknown;
|
|
491
|
+
/** Raw `a:cxnLst` XML content (connection sites). */
|
|
492
|
+
cxnLstXml?: unknown;
|
|
493
|
+
/** Raw `a:rect` XML content (text rectangle). */
|
|
494
|
+
rectXml?: unknown;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* XY-style adjustment handle (`a:ahXY`) on a custom geometry.
|
|
498
|
+
*
|
|
499
|
+
* Allows interactive editing of one or two guide values constrained to a
|
|
500
|
+
* rectangular range. Coordinates are formula references (e.g. `"adj1"`,
|
|
501
|
+
* `"w/2"`, `"0"`) preserved verbatim so they can re-emit unchanged.
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* ```ts
|
|
505
|
+
* const handle: AdjustHandleXY = {
|
|
506
|
+
* gdRefX: "adj1",
|
|
507
|
+
* minX: "0",
|
|
508
|
+
* maxX: "w",
|
|
509
|
+
* posX: "adj1",
|
|
510
|
+
* posY: "h/2",
|
|
511
|
+
* };
|
|
512
|
+
* // => satisfies AdjustHandleXY
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
interface AdjustHandleXY {
|
|
516
|
+
/** Guide reference for the X axis (`@_gdRefX`). */
|
|
517
|
+
gdRefX?: string;
|
|
518
|
+
/** Guide reference for the Y axis (`@_gdRefY`). */
|
|
519
|
+
gdRefY?: string;
|
|
520
|
+
/** Minimum X value, as a formula reference (`@_minX`). */
|
|
521
|
+
minX?: string;
|
|
522
|
+
/** Maximum X value (`@_maxX`). */
|
|
523
|
+
maxX?: string;
|
|
524
|
+
/** Minimum Y value (`@_minY`). */
|
|
525
|
+
minY?: string;
|
|
526
|
+
/** Maximum Y value (`@_maxY`). */
|
|
527
|
+
maxY?: string;
|
|
528
|
+
/** Handle position X (formula or literal) from `a:pos/@_x`. */
|
|
529
|
+
posX?: string;
|
|
530
|
+
/** Handle position Y from `a:pos/@_y`. */
|
|
531
|
+
posY?: string;
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Polar-style adjustment handle (`a:ahPolar`) on a custom geometry.
|
|
535
|
+
*
|
|
536
|
+
* Drives a guide via radial distance and angle rather than XY coordinates.
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```ts
|
|
540
|
+
* const handle: AdjustHandlePolar = {
|
|
541
|
+
* gdRefR: "adj1",
|
|
542
|
+
* gdRefAng: "adj2",
|
|
543
|
+
* posX: "wd2",
|
|
544
|
+
* posY: "hd2",
|
|
545
|
+
* };
|
|
546
|
+
* // => satisfies AdjustHandlePolar
|
|
547
|
+
* ```
|
|
548
|
+
*/
|
|
549
|
+
interface AdjustHandlePolar {
|
|
550
|
+
/** Guide reference for the radial distance (`@_gdRefR`). */
|
|
551
|
+
gdRefR?: string;
|
|
552
|
+
/** Guide reference for the angle (`@_gdRefAng`). */
|
|
553
|
+
gdRefAng?: string;
|
|
554
|
+
/** Minimum radial value (`@_minR`). */
|
|
555
|
+
minR?: string;
|
|
556
|
+
/** Maximum radial value (`@_maxR`). */
|
|
557
|
+
maxR?: string;
|
|
558
|
+
/** Minimum angle (`@_minAng`). */
|
|
559
|
+
minAng?: string;
|
|
560
|
+
/** Maximum angle (`@_maxAng`). */
|
|
561
|
+
maxAng?: string;
|
|
562
|
+
/** Handle position X from `a:pos/@_x`. */
|
|
563
|
+
posX?: string;
|
|
564
|
+
/** Handle position Y from `a:pos/@_y`. */
|
|
565
|
+
posY?: string;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Connection site (`a:cxn`) on a custom geometry.
|
|
569
|
+
*
|
|
570
|
+
* Defines a point on a custom shape that connectors may snap to.
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```ts
|
|
574
|
+
* const cxn: ConnectionSite = { ang: "0", posX: "0", posY: "hd2" };
|
|
575
|
+
* // => satisfies ConnectionSite
|
|
576
|
+
* ```
|
|
577
|
+
*/
|
|
578
|
+
interface ConnectionSite {
|
|
579
|
+
/** Approach angle (`@_ang`) — formula or literal degree-1/60000 value. */
|
|
580
|
+
ang?: string;
|
|
581
|
+
/** Site position X from `a:pos/@_x`. */
|
|
582
|
+
posX?: string;
|
|
583
|
+
/** Site position Y from `a:pos/@_y`. */
|
|
584
|
+
posY?: string;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Typed text rectangle (`a:rect`) on a custom geometry.
|
|
588
|
+
*
|
|
589
|
+
* Each edge is the formula or literal string preserved from the source XML
|
|
590
|
+
* (`"l"`, `"t"`, `"r"`, `"b"`, or any guide name / formula).
|
|
591
|
+
*/
|
|
592
|
+
interface CustomGeometryTextRect {
|
|
593
|
+
/** Left edge formula reference (`@_l`). */
|
|
594
|
+
l?: string;
|
|
595
|
+
/** Top edge (`@_t`). */
|
|
596
|
+
t?: string;
|
|
597
|
+
/** Right edge (`@_r`). */
|
|
598
|
+
r?: string;
|
|
599
|
+
/** Bottom edge (`@_b`). */
|
|
600
|
+
b?: string;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Custom (non-preset) geometry path — only on shapes and pictures.
|
|
604
|
+
*
|
|
605
|
+
* Contains SVG path data and/or structured custom geometry paths
|
|
606
|
+
* parsed from `a:custGeom/a:pathLst`.
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* ```ts
|
|
610
|
+
* const custom: PptxCustomPathProperties = {
|
|
611
|
+
* pathData: "M 0 0 L 100 0 L 100 100 Z",
|
|
612
|
+
* pathWidth: 100,
|
|
613
|
+
* pathHeight: 100,
|
|
614
|
+
* };
|
|
615
|
+
* // => satisfies PptxCustomPathProperties
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
interface PptxCustomPathProperties {
|
|
619
|
+
/** SVG path data for custom shapes. */
|
|
620
|
+
pathData?: string;
|
|
621
|
+
/** Coordinate-space width for the custom path. */
|
|
622
|
+
pathWidth?: number;
|
|
623
|
+
/** Coordinate-space height for the custom path. */
|
|
624
|
+
pathHeight?: number;
|
|
625
|
+
/** Structured custom geometry paths for editing (maps to a:custGeom/a:pathLst). */
|
|
626
|
+
customGeometryPaths?: CustomGeometryPath[];
|
|
627
|
+
/** Raw a:gdLst/a:ahLst/a:cxnLst/a:rect XML preserved for round-trip serialization. */
|
|
628
|
+
customGeometryRawData?: CustomGeometryRawData;
|
|
629
|
+
/**
|
|
630
|
+
* Typed XY adjustment handles parsed from `a:custGeom/a:ahLst/a:ahXY`.
|
|
631
|
+
* SDK-built shapes can populate this and the writer will emit `<a:ahXY>` entries
|
|
632
|
+
* even when no raw XML was preserved.
|
|
633
|
+
*/
|
|
634
|
+
customGeometryAdjustHandlesXY?: AdjustHandleXY[];
|
|
635
|
+
/**
|
|
636
|
+
* Typed polar adjustment handles parsed from `a:custGeom/a:ahLst/a:ahPolar`.
|
|
637
|
+
*/
|
|
638
|
+
customGeometryAdjustHandlesPolar?: AdjustHandlePolar[];
|
|
639
|
+
/**
|
|
640
|
+
* Typed connection sites parsed from `a:custGeom/a:cxnLst/a:cxn`.
|
|
641
|
+
*/
|
|
642
|
+
customGeometryConnectionSites?: ConnectionSite[];
|
|
643
|
+
/**
|
|
644
|
+
* Typed text rectangle parsed from `a:custGeom/a:rect`. When present this is
|
|
645
|
+
* preferred over {@link customGeometryRawData}'s `rectXml` on save.
|
|
646
|
+
*/
|
|
647
|
+
customGeometryTextRect?: CustomGeometryTextRect;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* 3-D effect properties, text warp (WordArt) presets, and scene/shape bevel
|
|
652
|
+
* definitions parsed from OOXML `a:sp3d`, `a:scene3d`, and `a:bodyPr/a:prstTxWarp`.
|
|
653
|
+
*
|
|
654
|
+
* @module pptx-types/three-d
|
|
655
|
+
*/
|
|
656
|
+
/**
|
|
657
|
+
* Bevel preset type tokens from OOXML `a:bevelT/@prst` / `a:bevelB/@prst`.
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```ts
|
|
661
|
+
* const bevel: BevelPresetType = "circle";
|
|
662
|
+
* // => "circle" — one of: "circle" | "relaxedInset" | "cross" | "coolSlant" | "angle" | …
|
|
663
|
+
* ```
|
|
664
|
+
*/
|
|
665
|
+
type BevelPresetType = 'circle' | 'relaxedInset' | 'cross' | 'coolSlant' | 'angle' | 'softRound' | 'convex' | 'slope' | 'divot' | 'riblet' | 'hardEdge' | 'artDeco' | 'none';
|
|
666
|
+
/**
|
|
667
|
+
* Material preset type tokens from OOXML `a:sp3d/@prstMaterial`.
|
|
668
|
+
*
|
|
669
|
+
* @example
|
|
670
|
+
* ```ts
|
|
671
|
+
* const mat: MaterialPresetType = "plastic";
|
|
672
|
+
* // => "plastic" — one of: "matte" | "warmMatte" | "plastic" | "metal" | "dkEdge" | …
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
type MaterialPresetType = 'matte' | 'warmMatte' | 'plastic' | 'metal' | 'dkEdge' | 'softEdge' | 'flat' | 'softmetal' | 'clear' | 'powder' | 'translucentPowder' | 'legacyMatte' | 'legacyPlastic' | 'legacyMetal' | 'legacyWireframe';
|
|
676
|
+
/**
|
|
677
|
+
* 3D text body extrusion/bevel from `a:bodyPr/a:sp3d`.
|
|
678
|
+
*
|
|
679
|
+
* @example
|
|
680
|
+
* ```ts
|
|
681
|
+
* const text3d: Text3DStyle = {
|
|
682
|
+
* extrusionHeight: 57150,
|
|
683
|
+
* presetMaterial: "plastic",
|
|
684
|
+
* bevelTopType: "circle",
|
|
685
|
+
* bevelTopWidth: 25400,
|
|
686
|
+
* bevelTopHeight: 25400,
|
|
687
|
+
* };
|
|
688
|
+
* // => satisfies Text3DStyle
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
interface Text3DStyle {
|
|
692
|
+
/** Extrusion height (depth) in EMU. */
|
|
693
|
+
extrusionHeight?: number;
|
|
694
|
+
/** Extrusion colour as hex string. */
|
|
695
|
+
extrusionColor?: string;
|
|
696
|
+
/** Preset material, e.g. "matte", "plastic", "metal". */
|
|
697
|
+
presetMaterial?: MaterialPresetType;
|
|
698
|
+
/** Top bevel preset type. */
|
|
699
|
+
bevelTopType?: BevelPresetType;
|
|
700
|
+
/** Top bevel width in EMU. */
|
|
701
|
+
bevelTopWidth?: number;
|
|
702
|
+
/** Top bevel height in EMU. */
|
|
703
|
+
bevelTopHeight?: number;
|
|
704
|
+
/** Bottom bevel preset type. */
|
|
705
|
+
bevelBottomType?: BevelPresetType;
|
|
706
|
+
/** Bottom bevel width in EMU. */
|
|
707
|
+
bevelBottomWidth?: number;
|
|
708
|
+
/** Bottom bevel height in EMU. */
|
|
709
|
+
bevelBottomHeight?: number;
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* 3D scene/camera properties from `a:scene3d`.
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```ts
|
|
716
|
+
* const scene: Pptx3DScene = {
|
|
717
|
+
* cameraPreset: "perspectiveFront",
|
|
718
|
+
* lightRigType: "threePt",
|
|
719
|
+
* lightRigDirection: "t",
|
|
720
|
+
* };
|
|
721
|
+
* // => satisfies Pptx3DScene
|
|
722
|
+
* ```
|
|
723
|
+
*/
|
|
724
|
+
interface Pptx3DScene {
|
|
725
|
+
/** Camera preset type, e.g. "orthographicFront", "perspectiveFront". */
|
|
726
|
+
cameraPreset?: string;
|
|
727
|
+
/** Camera rotation around X axis in 1/60000 degrees. */
|
|
728
|
+
cameraRotX?: number;
|
|
729
|
+
/** Camera rotation around Y axis in 1/60000 degrees. */
|
|
730
|
+
cameraRotY?: number;
|
|
731
|
+
/** Camera rotation around Z axis in 1/60000 degrees. */
|
|
732
|
+
cameraRotZ?: number;
|
|
733
|
+
/** Light rig type, e.g. "threePt", "balanced", "harsh". */
|
|
734
|
+
lightRigType?: string;
|
|
735
|
+
/** Light rig direction, e.g. "t", "b", "l", "r", "tl". */
|
|
736
|
+
lightRigDirection?: string;
|
|
737
|
+
/** Whether a 3D backdrop plane is present (`a:backdrop`). */
|
|
738
|
+
hasBackdrop?: boolean;
|
|
739
|
+
/** Backdrop plane anchor X in EMU. */
|
|
740
|
+
backdropAnchorX?: number;
|
|
741
|
+
/** Backdrop plane anchor Y in EMU. */
|
|
742
|
+
backdropAnchorY?: number;
|
|
743
|
+
/** Backdrop plane anchor Z in EMU. */
|
|
744
|
+
backdropAnchorZ?: number;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* 3D shape extrusion/bevel from `a:sp3d`.
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* ```ts
|
|
751
|
+
* const shape3d: Pptx3DShape = {
|
|
752
|
+
* extrusionHeight: 76200,
|
|
753
|
+
* extrusionColor: "#4F81BD",
|
|
754
|
+
* presetMaterial: "metal",
|
|
755
|
+
* bevelTopType: "circle",
|
|
756
|
+
* bevelTopWidth: 12700,
|
|
757
|
+
* bevelTopHeight: 12700,
|
|
758
|
+
* };
|
|
759
|
+
* // => satisfies Pptx3DShape
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
interface Pptx3DShape {
|
|
763
|
+
/** Extrusion height in EMU. */
|
|
764
|
+
extrusionHeight?: number;
|
|
765
|
+
/** Extrusion colour. */
|
|
766
|
+
extrusionColor?: string;
|
|
767
|
+
/** Contour width in EMU. */
|
|
768
|
+
contourWidth?: number;
|
|
769
|
+
/** Contour colour. */
|
|
770
|
+
contourColor?: string;
|
|
771
|
+
/** Preset material, e.g. "matte", "warmMatte", "metal". */
|
|
772
|
+
presetMaterial?: string;
|
|
773
|
+
/** Top bevel type, e.g. "circle", "relaxedInset". */
|
|
774
|
+
bevelTopType?: string;
|
|
775
|
+
/** Top bevel width in EMU. */
|
|
776
|
+
bevelTopWidth?: number;
|
|
777
|
+
/** Top bevel height in EMU. */
|
|
778
|
+
bevelTopHeight?: number;
|
|
779
|
+
/** Bottom bevel type, e.g. "circle", "relaxedInset". */
|
|
780
|
+
bevelBottomType?: string;
|
|
781
|
+
/** Bottom bevel width in EMU. */
|
|
782
|
+
bevelBottomWidth?: number;
|
|
783
|
+
/** Bottom bevel height in EMU. */
|
|
784
|
+
bevelBottomHeight?: number;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Known OOXML preset text warp types (WordArt transforms).
|
|
788
|
+
*
|
|
789
|
+
* Falls back to `string` for unknown presets not yet catalogued.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```ts
|
|
793
|
+
* const warp: PptxTextWarpPreset = "textArchUp";
|
|
794
|
+
* // => "textArchUp" — one of: "textNoShape" | "textPlain" | "textStop" | "textArchUp" | …
|
|
795
|
+
* ```
|
|
796
|
+
*/
|
|
797
|
+
type PptxTextWarpPreset = 'textNoShape' | 'textPlain' | 'textStop' | 'textTriangle' | 'textTriangleInverted' | 'textChevron' | 'textChevronInverted' | 'textRingInside' | 'textRingOutside' | 'textArchUp' | 'textArchDown' | 'textCircle' | 'textButton' | 'textArchUpPour' | 'textArchDownPour' | 'textCirclePour' | 'textButtonPour' | 'textCurveUp' | 'textCurveDown' | 'textCanUp' | 'textCanDown' | 'textWave1' | 'textWave2' | 'textWave4' | 'textDoubleWave1' | 'textInflate' | 'textDeflate' | 'textInflateBottom' | 'textDeflateBottom' | 'textInflateTop' | 'textDeflateTop' | 'textFadeRight' | 'textFadeLeft' | 'textFadeUp' | 'textFadeDown' | 'textSlantUp' | 'textSlantDown' | 'textCascadeUp' | 'textCascadeDown' | 'textDeflateInflate' | 'textDeflateInflateDeflate' | string;
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* Shape visual styling types: fill, stroke, effects, and connectors.
|
|
801
|
+
*
|
|
802
|
+
* {@link ShapeStyle} is the main type attached to any element that has
|
|
803
|
+
* visible geometry (shapes, connectors, images). It covers:
|
|
804
|
+
* - **Fill**: solid, gradient, pattern, image, and theme fills
|
|
805
|
+
* - **Stroke**: colour, width, dash pattern, line join/cap
|
|
806
|
+
* - **Effects**: shadow, glow, soft-edge, reflection, blur
|
|
807
|
+
* - **Connectors**: arrow-head types and connection points
|
|
808
|
+
* - **3-D**: scene camera and shape extrusion/bevel
|
|
809
|
+
*
|
|
810
|
+
* All spatial values are stored in **pixels** (pre-converted from EMU).
|
|
811
|
+
* Opacity values are normalised to the 0–1 range.
|
|
812
|
+
*
|
|
813
|
+
* @module pptx-types/shape-style
|
|
814
|
+
*/
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Comprehensive visual style for a shape, connector, or image element.
|
|
818
|
+
*
|
|
819
|
+
* All fields are optional. When absent, the element inherits from theme
|
|
820
|
+
* or layout defaults. The interface models both simple styling (solid fill +
|
|
821
|
+
* basic stroke) and advanced effects (multiple shadow layers, gradient
|
|
822
|
+
* fills, 3-D extrusion).
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* // Simple blue filled shape with a thin black outline:
|
|
827
|
+
* const simple: ShapeStyle = {
|
|
828
|
+
* fillColor: "#0055AA",
|
|
829
|
+
* fillMode: "solid",
|
|
830
|
+
* strokeColor: "#000000",
|
|
831
|
+
* strokeWidth: 1,
|
|
832
|
+
* };
|
|
833
|
+
*
|
|
834
|
+
* // Gradient fill with a soft shadow:
|
|
835
|
+
* const fancy: ShapeStyle = {
|
|
836
|
+
* fillMode: "gradient",
|
|
837
|
+
* fillGradientType: "linear",
|
|
838
|
+
* fillGradientAngle: 135,
|
|
839
|
+
* fillGradientStops: [
|
|
840
|
+
* { color: "#FF6B6B", position: 0 },
|
|
841
|
+
* { color: "#556270", position: 1 },
|
|
842
|
+
* ],
|
|
843
|
+
* shadowColor: "#000000",
|
|
844
|
+
* shadowBlur: 10,
|
|
845
|
+
* shadowOffsetX: 4,
|
|
846
|
+
* shadowOffsetY: 4,
|
|
847
|
+
* shadowOpacity: 0.3,
|
|
848
|
+
* };
|
|
849
|
+
* // => both satisfy the ShapeStyle interface
|
|
850
|
+
* ```
|
|
851
|
+
*/
|
|
852
|
+
interface ShapeStyle {
|
|
853
|
+
fillColor?: string;
|
|
854
|
+
/**
|
|
855
|
+
* Raw XML colour-choice node preserved from `a:solidFill` for round-trip
|
|
856
|
+
* serialisation. Captures `a:schemeClr` / `a:sysClr` / `a:prstClr` /
|
|
857
|
+
* `a:srgbClr` plus colour transforms (`lumMod`, `lumOff`, `tint`,
|
|
858
|
+
* `shade`, `satMod`, `alpha`, …). On save we re-emit verbatim when the
|
|
859
|
+
* resolved {@link fillColor} still matches this node, otherwise we fall
|
|
860
|
+
* back to canonical `<a:srgbClr>`.
|
|
861
|
+
*/
|
|
862
|
+
fillColorXml?: XmlObject;
|
|
863
|
+
fillGradient?: string;
|
|
864
|
+
fillMode?: 'solid' | 'gradient' | 'pattern' | 'none' | 'image' | 'theme' | 'group';
|
|
865
|
+
fillPatternPreset?: string;
|
|
866
|
+
fillPatternBackgroundColor?: string;
|
|
867
|
+
/** Raw XML node for pattern fill foreground colour (preserves color transforms). */
|
|
868
|
+
fillPatternFgClrXml?: XmlObject;
|
|
869
|
+
/** Raw XML node for pattern fill background colour (preserves color transforms). */
|
|
870
|
+
fillPatternBgClrXml?: XmlObject;
|
|
871
|
+
/** Data-URI or URL for image fill (when fillMode === "image"). */
|
|
872
|
+
fillImageUrl?: string;
|
|
873
|
+
/** How the image is sized within the shape: stretch to fill, or tile/repeat. */
|
|
874
|
+
fillImageMode?: 'stretch' | 'tile';
|
|
875
|
+
fillGradientStops?: Array<{
|
|
876
|
+
color: string;
|
|
877
|
+
position: number;
|
|
878
|
+
opacity?: number;
|
|
879
|
+
/** Raw XML colour node preserved for round-trip (e.g. a:schemeClr with transforms). */
|
|
880
|
+
originalColorXml?: XmlObject;
|
|
881
|
+
}>;
|
|
882
|
+
fillGradientAngle?: number;
|
|
883
|
+
fillGradientType?: 'linear' | 'radial';
|
|
884
|
+
/** Path gradient sub-type from `a:path/@path` (e.g. "circle", "rect", "shape"). */
|
|
885
|
+
fillGradientPathType?: 'circle' | 'rect' | 'shape';
|
|
886
|
+
/** Focal point for path (radial) gradients, derived from `a:fillToRect`.
|
|
887
|
+
* Values are 0..1 fractions relative to shape bounds. */
|
|
888
|
+
fillGradientFocalPoint?: {
|
|
889
|
+
x: number;
|
|
890
|
+
y: number;
|
|
891
|
+
};
|
|
892
|
+
/** Raw fillToRect LTRB values (0..1 fractions) from `a:fillToRect`.
|
|
893
|
+
* Defines the inner rectangle where the gradient reaches its final stop.
|
|
894
|
+
* l/t are insets from left/top edges; r/b are insets from right/bottom edges. */
|
|
895
|
+
fillGradientFillToRect?: {
|
|
896
|
+
l: number;
|
|
897
|
+
t: number;
|
|
898
|
+
r: number;
|
|
899
|
+
b: number;
|
|
900
|
+
};
|
|
901
|
+
/** Gradient tile flip mode (`a:gradFill/@flip`).
|
|
902
|
+
* `none` = no tiling flip (default), `x|y|xy` = mirror in the named axis. */
|
|
903
|
+
fillGradientFlip?: 'none' | 'x' | 'y' | 'xy';
|
|
904
|
+
/** Whether the gradient rotates with the shape (`a:gradFill/@rotWithShape`).
|
|
905
|
+
* Defaults to true per the schema; preserved for round-trip when the source
|
|
906
|
+
* authored the attribute explicitly. */
|
|
907
|
+
fillGradientRotWithShape?: boolean;
|
|
908
|
+
/** Whether the linear gradient is scaled to the shape (`a:lin/@scaled`).
|
|
909
|
+
* Defaults to true per the schema; preserved for round-trip. */
|
|
910
|
+
fillGradientScaled?: boolean;
|
|
911
|
+
fillOpacity?: number;
|
|
912
|
+
strokeColor?: string;
|
|
913
|
+
/**
|
|
914
|
+
* Raw XML colour-choice node preserved from `a:ln/a:solidFill` for
|
|
915
|
+
* round-trip serialisation. See {@link fillColorXml} for the rationale.
|
|
916
|
+
*/
|
|
917
|
+
strokeColorXml?: XmlObject;
|
|
918
|
+
strokeWidth?: number;
|
|
919
|
+
strokeOpacity?: number;
|
|
920
|
+
strokeDash?: StrokeDashType;
|
|
921
|
+
/** Line join style (`a:ln/@join`): round, bevel, or miter. */
|
|
922
|
+
lineJoin?: 'round' | 'bevel' | 'miter';
|
|
923
|
+
/** Miter limit (`a:miter/@lim`) in EMU-percent units (default 800000 = 8.0). Only meaningful when lineJoin is 'miter'. */
|
|
924
|
+
miterLimit?: number;
|
|
925
|
+
/** Line cap style (`a:ln/@cap`): flat, rnd, or sq. */
|
|
926
|
+
lineCap?: 'flat' | 'rnd' | 'sq';
|
|
927
|
+
/** Compound line type (`a:ln/@cmpd`). */
|
|
928
|
+
compoundLine?: 'sng' | 'dbl' | 'thickThin' | 'thinThick' | 'tri';
|
|
929
|
+
/** Pen line alignment (`a:ln/@algn`): `ctr` (centre, default) or `in` (inside). */
|
|
930
|
+
lineAlignment?: 'ctr' | 'in';
|
|
931
|
+
shadowColor?: string;
|
|
932
|
+
shadowBlur?: number;
|
|
933
|
+
shadowOffsetX?: number;
|
|
934
|
+
shadowOffsetY?: number;
|
|
935
|
+
shadowOpacity?: number;
|
|
936
|
+
/** Preset shadow name from `a:prstShdw/@prst` (e.g. "shdw1"..."shdw20"). */
|
|
937
|
+
presetShadowName?: string;
|
|
938
|
+
/** Shadow angle in degrees (0-360). Parsed from `@_dir` (60000ths of a degree). */
|
|
939
|
+
shadowAngle?: number;
|
|
940
|
+
/** Shadow distance in pixels. Parsed from `@_dist` (EMUs). */
|
|
941
|
+
shadowDistance?: number;
|
|
942
|
+
/** Whether shadow rotates with shape. Parsed from `@_rotWithShape`. */
|
|
943
|
+
shadowRotateWithShape?: boolean;
|
|
944
|
+
/** Outer-shadow horizontal scaling (`a:outerShdw/@sx`) in 1000ths of a percent (default 100000 = 100%). */
|
|
945
|
+
shadowScaleX?: number;
|
|
946
|
+
/** Outer-shadow vertical scaling (`a:outerShdw/@sy`). */
|
|
947
|
+
shadowScaleY?: number;
|
|
948
|
+
/** Outer-shadow horizontal skew (`a:outerShdw/@kx`) in 60000ths of a degree. */
|
|
949
|
+
shadowSkewX?: number;
|
|
950
|
+
/** Outer-shadow vertical skew (`a:outerShdw/@ky`). */
|
|
951
|
+
shadowSkewY?: number;
|
|
952
|
+
/** Outer-shadow alignment (`a:outerShdw/@algn`). */
|
|
953
|
+
shadowAlignment?: 'tl' | 't' | 'tr' | 'l' | 'ctr' | 'r' | 'bl' | 'b' | 'br';
|
|
954
|
+
/** Inner-shadow rotateWithShape (`a:innerShdw/@rotWithShape`). */
|
|
955
|
+
innerShadowRotateWithShape?: boolean;
|
|
956
|
+
/** Reflection fade direction (`a:reflection/@fadeDir`) in 60000ths of a degree. */
|
|
957
|
+
reflectionFadeDirection?: number;
|
|
958
|
+
/** Reflection horizontal scaling (`a:reflection/@sx`). */
|
|
959
|
+
reflectionScaleX?: number;
|
|
960
|
+
/** Reflection vertical scaling (`a:reflection/@sy`). */
|
|
961
|
+
reflectionScaleY?: number;
|
|
962
|
+
/** Reflection horizontal skew (`a:reflection/@kx`). */
|
|
963
|
+
reflectionSkewX?: number;
|
|
964
|
+
/** Reflection vertical skew (`a:reflection/@ky`). */
|
|
965
|
+
reflectionSkewY?: number;
|
|
966
|
+
/** Reflection alignment (`a:reflection/@algn`). */
|
|
967
|
+
reflectionAlignment?: 'tl' | 't' | 'tr' | 'l' | 'ctr' | 'r' | 'bl' | 'b' | 'br';
|
|
968
|
+
/** Reflection rotateWithShape (`a:reflection/@rotWithShape`). */
|
|
969
|
+
reflectionRotateWithShape?: boolean;
|
|
970
|
+
/** Reflection start position (`a:reflection/@stPos`) as 0-1 fraction. */
|
|
971
|
+
reflectionStartPosition?: number;
|
|
972
|
+
/** Multiple shadow layers (for advanced effects). */
|
|
973
|
+
shadows?: ShadowEffect[];
|
|
974
|
+
glowColor?: string;
|
|
975
|
+
glowRadius?: number;
|
|
976
|
+
glowOpacity?: number;
|
|
977
|
+
softEdgeRadius?: number;
|
|
978
|
+
/** Inner shadow colour (`a:innerShdw`). */
|
|
979
|
+
innerShadowColor?: string;
|
|
980
|
+
/** Inner shadow opacity (0-1). */
|
|
981
|
+
innerShadowOpacity?: number;
|
|
982
|
+
/** Inner shadow blur radius in px. */
|
|
983
|
+
innerShadowBlur?: number;
|
|
984
|
+
/** Inner shadow horizontal offset in px. */
|
|
985
|
+
innerShadowOffsetX?: number;
|
|
986
|
+
/** Inner shadow vertical offset in px. */
|
|
987
|
+
innerShadowOffsetY?: number;
|
|
988
|
+
/** Reflection effect — distance from shape bottom in px. */
|
|
989
|
+
reflectionBlurRadius?: number;
|
|
990
|
+
/** Reflection start opacity (0-1). */
|
|
991
|
+
reflectionStartOpacity?: number;
|
|
992
|
+
/** Reflection end opacity (0-1). */
|
|
993
|
+
reflectionEndOpacity?: number;
|
|
994
|
+
/** Reflection end position (0-1 fraction of shape height). */
|
|
995
|
+
reflectionEndPosition?: number;
|
|
996
|
+
/** Reflection direction in degrees. */
|
|
997
|
+
reflectionDirection?: number;
|
|
998
|
+
/** Reflection rotation in degrees (`a:reflection/@rot` in 60000ths). */
|
|
999
|
+
reflectionRotation?: number;
|
|
1000
|
+
/** Reflection distance in px. */
|
|
1001
|
+
reflectionDistance?: number;
|
|
1002
|
+
/** Standalone blur effect radius in px (`a:effectLst > a:blur`). */
|
|
1003
|
+
blurRadius?: number;
|
|
1004
|
+
/** Whether the blur effect grows the bounds of the shape (`a:blur/@grow`). */
|
|
1005
|
+
blurGrow?: boolean;
|
|
1006
|
+
connectorStartArrow?: ConnectorArrowType;
|
|
1007
|
+
/** Start arrow width size ('sm' | 'med' | 'lg'). */
|
|
1008
|
+
connectorStartArrowWidth?: 'sm' | 'med' | 'lg';
|
|
1009
|
+
/** Start arrow length size ('sm' | 'med' | 'lg'). */
|
|
1010
|
+
connectorStartArrowLength?: 'sm' | 'med' | 'lg';
|
|
1011
|
+
connectorEndArrow?: ConnectorArrowType;
|
|
1012
|
+
/** End arrow width size ('sm' | 'med' | 'lg'). */
|
|
1013
|
+
connectorEndArrowWidth?: 'sm' | 'med' | 'lg';
|
|
1014
|
+
/** End arrow length size ('sm' | 'med' | 'lg'). */
|
|
1015
|
+
connectorEndArrowLength?: 'sm' | 'med' | 'lg';
|
|
1016
|
+
/** Connection point for the start of a connector. */
|
|
1017
|
+
connectorStartConnection?: ConnectorConnectionPoint;
|
|
1018
|
+
/** Connection point for the end of a connector. */
|
|
1019
|
+
connectorEndConnection?: ConnectorConnectionPoint;
|
|
1020
|
+
/** Custom dash segments array (`a:custDash/a:ds`). Each entry has dash length and space length in EMU. */
|
|
1021
|
+
customDashSegments?: Array<{
|
|
1022
|
+
dash: number;
|
|
1023
|
+
space: number;
|
|
1024
|
+
}>;
|
|
1025
|
+
/** 3D scene/camera settings from `a:scene3d`. */
|
|
1026
|
+
scene3d?: Pptx3DScene;
|
|
1027
|
+
/** 3D shape extrusion/bevel from `a:sp3d`. */
|
|
1028
|
+
shape3d?: Pptx3DShape;
|
|
1029
|
+
/** Line-level shadow colour from `a:ln/a:effectLst/a:outerShdw`. */
|
|
1030
|
+
lineShadowColor?: string;
|
|
1031
|
+
/** Line-level shadow opacity (0-1). */
|
|
1032
|
+
lineShadowOpacity?: number;
|
|
1033
|
+
/** Line-level shadow blur radius in px. */
|
|
1034
|
+
lineShadowBlur?: number;
|
|
1035
|
+
/** Line-level shadow horizontal offset in px. */
|
|
1036
|
+
lineShadowOffsetX?: number;
|
|
1037
|
+
/** Line-level shadow vertical offset in px. */
|
|
1038
|
+
lineShadowOffsetY?: number;
|
|
1039
|
+
/** Line-level glow colour from `a:ln/a:effectLst/a:glow`. */
|
|
1040
|
+
lineGlowColor?: string;
|
|
1041
|
+
/** Line-level glow radius in px. */
|
|
1042
|
+
lineGlowRadius?: number;
|
|
1043
|
+
/** Line-level glow opacity (0-1). */
|
|
1044
|
+
lineGlowOpacity?: number;
|
|
1045
|
+
/** Raw `a:effectDag` XML node preserved for round-trip serialisation. */
|
|
1046
|
+
effectDagXml?: XmlObject;
|
|
1047
|
+
/** Grayscale flag from effectDag `a:grayscl`. */
|
|
1048
|
+
dagGrayscale?: boolean;
|
|
1049
|
+
/** Bi-level threshold (0-100) from effectDag `a:biLevel`. */
|
|
1050
|
+
dagBiLevel?: number;
|
|
1051
|
+
/** Brightness adjustment (-100 to 100) from effectDag `a:lum/@bright`. */
|
|
1052
|
+
dagLumBrightness?: number;
|
|
1053
|
+
/** Contrast adjustment (-100 to 100) from effectDag `a:lum/@contrast`. */
|
|
1054
|
+
dagLumContrast?: number;
|
|
1055
|
+
/** Hue rotation in degrees (0-360) from effectDag `a:hsl/@hue`. */
|
|
1056
|
+
dagHslHue?: number;
|
|
1057
|
+
/** Saturation adjustment from effectDag `a:hsl/@sat`. */
|
|
1058
|
+
dagHslSaturation?: number;
|
|
1059
|
+
/** Luminance adjustment from effectDag `a:hsl/@lum`. */
|
|
1060
|
+
dagHslLuminance?: number;
|
|
1061
|
+
/** Alpha modulation fixed (0-100) from effectDag `a:alphaModFix`. */
|
|
1062
|
+
dagAlphaModFix?: number;
|
|
1063
|
+
/** Tint hue in degrees from effectDag `a:tint/@hue`. */
|
|
1064
|
+
dagTintHue?: number;
|
|
1065
|
+
/** Tint amount (0-100) from effectDag `a:tint/@amt`. */
|
|
1066
|
+
dagTintAmount?: number;
|
|
1067
|
+
/** Duotone colour pair from effectDag `a:duotone`. */
|
|
1068
|
+
dagDuotone?: {
|
|
1069
|
+
color1: string;
|
|
1070
|
+
color2: string;
|
|
1071
|
+
};
|
|
1072
|
+
/** Fill overlay blend mode from effectDag `a:fillOverlay/@blend`. */
|
|
1073
|
+
dagFillOverlayBlend?: 'over' | 'mult' | 'screen' | 'darken' | 'lighten';
|
|
1074
|
+
/** `<a:lnRef @idx>` — 1-based index into the theme's lnStyleLst. */
|
|
1075
|
+
lnRefIdx?: number;
|
|
1076
|
+
/** Raw XML colour child of `<a:lnRef>` (e.g. `<a:schemeClr>` with transforms). */
|
|
1077
|
+
lnRefColorXml?: XmlObject;
|
|
1078
|
+
/** `<a:fillRef @idx>` — 1-based index into fillStyleLst (1-3) or bgFillStyleLst (1001-1003). */
|
|
1079
|
+
fillRefIdx?: number;
|
|
1080
|
+
/** Raw XML colour child of `<a:fillRef>`. */
|
|
1081
|
+
fillRefColorXml?: XmlObject;
|
|
1082
|
+
/** `<a:effectRef @idx>` — 1-based index into the theme's effectStyleLst. */
|
|
1083
|
+
effectRefIdx?: number;
|
|
1084
|
+
/** Raw XML colour child of `<a:effectRef>`. */
|
|
1085
|
+
effectRefColorXml?: XmlObject;
|
|
1086
|
+
/** `<a:fontRef @idx>` — typically `major`, `minor`, or `none`. */
|
|
1087
|
+
fontRefIdx?: string;
|
|
1088
|
+
/** Raw XML colour child of `<a:fontRef>`. */
|
|
1089
|
+
fontRefColorXml?: XmlObject;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* Text-related types: rich text styles, bullet metadata, and text segments.
|
|
1094
|
+
*
|
|
1095
|
+
* These types model the contents of `<a:r>`, `<a:rPr>`, `<a:pPr>`,
|
|
1096
|
+
* and `<a:bodyPr>` nodes from the OpenXML Drawing namespace.
|
|
1097
|
+
*
|
|
1098
|
+
* @module pptx-types/text
|
|
1099
|
+
*/
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* Rich text style properties for a text run or paragraph.
|
|
1103
|
+
*
|
|
1104
|
+
* Combines character-level formatting (font, bold, colour …),
|
|
1105
|
+
* paragraph-level controls (alignment, spacing, indentation), and
|
|
1106
|
+
* body-level properties (autofit, insets, text direction). All
|
|
1107
|
+
* fields are optional — unset properties inherit from layout/master
|
|
1108
|
+
* placeholders or theme defaults.
|
|
1109
|
+
*
|
|
1110
|
+
* @remarks
|
|
1111
|
+
* Font sizes are stored in **points**. Spatial measurements (insets,
|
|
1112
|
+
* margins) are in **pixels** (pre-converted from EMU during parsing).
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```ts
|
|
1116
|
+
* const heading: TextStyle = {
|
|
1117
|
+
* fontFamily: "Montserrat",
|
|
1118
|
+
* fontSize: 36,
|
|
1119
|
+
* bold: true,
|
|
1120
|
+
* color: "#1A1A2E",
|
|
1121
|
+
* align: "center",
|
|
1122
|
+
* lineSpacing: 1.15,
|
|
1123
|
+
* };
|
|
1124
|
+
*
|
|
1125
|
+
* const body: TextStyle = {
|
|
1126
|
+
* fontFamily: "Open Sans",
|
|
1127
|
+
* fontSize: 14,
|
|
1128
|
+
* color: "#444444",
|
|
1129
|
+
* align: "left",
|
|
1130
|
+
* paragraphSpacingAfter: 8,
|
|
1131
|
+
* };
|
|
1132
|
+
* // => both satisfy the TextStyle interface
|
|
1133
|
+
* ```
|
|
1134
|
+
*/
|
|
1135
|
+
interface TextStyle {
|
|
1136
|
+
fontFamily?: string;
|
|
1137
|
+
fontSize?: number;
|
|
1138
|
+
/** When true, renderer should shrink text to fit the shape bounds. */
|
|
1139
|
+
autoFit?: boolean;
|
|
1140
|
+
/** Explicit autofit mode from OOXML body properties.
|
|
1141
|
+
* - 'shrink': `a:spAutoFit` — shrink text on overflow
|
|
1142
|
+
* - 'normal': `a:normAutofit` — normal auto-fit (with optional fontScale)
|
|
1143
|
+
* - 'none': `a:noAutofit` — explicitly no auto-fit (text overflows)
|
|
1144
|
+
* - undefined: no autofit element present (inherit from layout/master)
|
|
1145
|
+
*/
|
|
1146
|
+
autoFitMode?: 'shrink' | 'normal' | 'none';
|
|
1147
|
+
/** Font scale percentage for normAutofit (e.g. 0.9 = 90%). Only meaningful when autoFit is true. */
|
|
1148
|
+
autoFitFontScale?: number;
|
|
1149
|
+
/** Line spacing reduction for normAutofit (e.g. 0.2 = reduce by 20%). Only meaningful when autoFit is true. */
|
|
1150
|
+
autoFitLineSpacingReduction?: number;
|
|
1151
|
+
bold?: boolean;
|
|
1152
|
+
italic?: boolean;
|
|
1153
|
+
underline?: boolean;
|
|
1154
|
+
/** Specific underline style (e.g. "sng", "dbl", "wavy"). Falls back to "sng" when `underline` is true. */
|
|
1155
|
+
underlineStyle?: UnderlineStyle;
|
|
1156
|
+
/** Underline colour as hex string (`a:uFill` / `a:uLn`). When absent, inherits text colour. */
|
|
1157
|
+
underlineColor?: string;
|
|
1158
|
+
/**
|
|
1159
|
+
* When true, the source authored `<a:u val="none"/>` to explicitly suppress
|
|
1160
|
+
* underline (rather than omitting the attribute entirely). Preserved so the
|
|
1161
|
+
* writer can re-emit the explicit `none` token instead of dropping it.
|
|
1162
|
+
*/
|
|
1163
|
+
underlineExplicitNone?: boolean;
|
|
1164
|
+
/**
|
|
1165
|
+
* Underline line properties parsed from `<a:rPr><a:uLn>` — width, dash
|
|
1166
|
+
* preset, and end caps. Captured as a typed object so the writer can
|
|
1167
|
+
* round-trip the line styling that previously was dropped (only the
|
|
1168
|
+
* solidFill colour was carried before).
|
|
1169
|
+
*/
|
|
1170
|
+
underlineLine?: {
|
|
1171
|
+
/** Line width in EMU (raw OOXML) for `a:uLn/@w`. */
|
|
1172
|
+
widthEmu?: number;
|
|
1173
|
+
/** Compound line type (`a:uLn/@cmpd`). */
|
|
1174
|
+
compound?: string;
|
|
1175
|
+
/** Cap style (`a:uLn/@cap`). */
|
|
1176
|
+
cap?: string;
|
|
1177
|
+
/** Pen alignment (`a:uLn/@algn`). */
|
|
1178
|
+
algn?: string;
|
|
1179
|
+
/** Preset dash value (`a:uLn/a:prstDash/@val`). */
|
|
1180
|
+
prstDash?: string;
|
|
1181
|
+
/** Raw `a:uLn/a:headEnd` XML preserved verbatim. */
|
|
1182
|
+
headEndXml?: XmlObject;
|
|
1183
|
+
/** Raw `a:uLn/a:tailEnd` XML preserved verbatim. */
|
|
1184
|
+
tailEndXml?: XmlObject;
|
|
1185
|
+
};
|
|
1186
|
+
/** When `<a:uLnTx/>` is present — underline line follows the text run line. */
|
|
1187
|
+
underlineLineFollowsText?: boolean;
|
|
1188
|
+
/** When `<a:uFillTx/>` is present — underline fill follows the text run fill. */
|
|
1189
|
+
underlineFillFollowsText?: boolean;
|
|
1190
|
+
strikethrough?: boolean;
|
|
1191
|
+
/** Specific strike type: single or double from `a:rPr/@strike`. */
|
|
1192
|
+
strikeType?: 'sngStrike' | 'dblStrike';
|
|
1193
|
+
/** Text outline width in px (`a:rPr > a:ln/@w` in EMU). */
|
|
1194
|
+
textOutlineWidth?: number;
|
|
1195
|
+
/** Text outline colour as hex string (`a:rPr > a:ln > a:solidFill`). */
|
|
1196
|
+
textOutlineColor?: string;
|
|
1197
|
+
/** When true, the text body has no fill (`a:rPr > a:noFill`), producing hollow/outline-only text. */
|
|
1198
|
+
textFillNone?: boolean;
|
|
1199
|
+
/** Superscript/subscript baseline shift as percentage (`a:rPr/@baseline`). Positive = super, negative = sub. */
|
|
1200
|
+
baseline?: number;
|
|
1201
|
+
/** Character spacing in hundredths of a point (`a:rPr/@spc`). */
|
|
1202
|
+
characterSpacing?: number;
|
|
1203
|
+
/** Kerning threshold in hundredths of a point (`a:rPr/@kern`). 0 = none. */
|
|
1204
|
+
kerning?: number;
|
|
1205
|
+
/** Text highlight colour as hex string (`a:highlight`). */
|
|
1206
|
+
highlightColor?: string;
|
|
1207
|
+
/** Text-level gradient fill CSS string (from `a:rPr > a:gradFill`). */
|
|
1208
|
+
textFillGradient?: string;
|
|
1209
|
+
/** Structured gradient stops for text fill round-trip serialization. */
|
|
1210
|
+
textFillGradientStops?: Array<{
|
|
1211
|
+
color: string;
|
|
1212
|
+
position: number;
|
|
1213
|
+
opacity?: number;
|
|
1214
|
+
}>;
|
|
1215
|
+
/** Gradient angle in degrees for text fill round-trip. */
|
|
1216
|
+
textFillGradientAngle?: number;
|
|
1217
|
+
/** Gradient type for text fill round-trip ('linear' | 'radial'). */
|
|
1218
|
+
textFillGradientType?: 'linear' | 'radial';
|
|
1219
|
+
/** Text-level pattern fill preset (from `a:rPr > a:pattFill`). */
|
|
1220
|
+
textFillPattern?: string;
|
|
1221
|
+
/** Text-level pattern foreground colour. */
|
|
1222
|
+
textFillPatternForeground?: string;
|
|
1223
|
+
/** Text-level pattern background colour. */
|
|
1224
|
+
textFillPatternBackground?: string;
|
|
1225
|
+
hyperlink?: string;
|
|
1226
|
+
/** Relationship ID for the hyperlink (`a:hlinkClick/@r:id`) — preserved for round-trip serialization. */
|
|
1227
|
+
hyperlinkRId?: string;
|
|
1228
|
+
/** Hyperlink tooltip text (`a:hlinkClick/@tooltip`). */
|
|
1229
|
+
hyperlinkTooltip?: string;
|
|
1230
|
+
/** Hyperlink action type (`a:hlinkClick/@action`). */
|
|
1231
|
+
hyperlinkAction?: string;
|
|
1232
|
+
/** Whether the hyperlink target is an internal slide jump (targetSlideIndex style). */
|
|
1233
|
+
hyperlinkTargetSlideIndex?: number;
|
|
1234
|
+
color?: string;
|
|
1235
|
+
/**
|
|
1236
|
+
* Raw XML colour-choice node preserved from `a:rPr/a:solidFill` for
|
|
1237
|
+
* round-trip serialisation. Captures `a:schemeClr` / `a:sysClr` /
|
|
1238
|
+
* `a:prstClr` / `a:srgbClr` plus colour transforms. On save we re-emit
|
|
1239
|
+
* verbatim when the resolved {@link color} still matches this node.
|
|
1240
|
+
*/
|
|
1241
|
+
colorXml?: XmlObject;
|
|
1242
|
+
align?: 'left' | 'center' | 'right' | 'justify' | 'justLow' | 'dist' | 'thaiDist';
|
|
1243
|
+
vAlign?: 'top' | 'middle' | 'bottom';
|
|
1244
|
+
/** Right-to-left paragraph/run direction (`a:pPr/@rtl`, `a:rPr/@rtl`). */
|
|
1245
|
+
rtl?: boolean;
|
|
1246
|
+
/** Body text direction (`a:bodyPr/@vert`).
|
|
1247
|
+
*
|
|
1248
|
+
* Values map to OOXML `a:bodyPr/@vert` attribute values:
|
|
1249
|
+
* - `"horizontal"` — default horizontal text (`horz`)
|
|
1250
|
+
* - `"vertical"` — standard vertical text, right-to-left columns (`vert`)
|
|
1251
|
+
* - `"vertical270"` — text rotated 270 degrees (`vert270`)
|
|
1252
|
+
* - `"eaVert"` — East Asian vertical text with CJK glyphs upright (`eaVert`)
|
|
1253
|
+
* - `"wordArtVert"` — WordArt vertical, each character upright stacked (`wordArtVert`)
|
|
1254
|
+
* - `"wordArtVertRtl"` — WordArt vertical, right-to-left direction (`wordArtVertRtl`)
|
|
1255
|
+
* - `"mongolianVert"` — Mongolian vertical text, left-to-right columns (`mongolianVert`)
|
|
1256
|
+
*/
|
|
1257
|
+
textDirection?: 'horizontal' | 'vertical' | 'vertical270' | 'eaVert' | 'wordArtVert' | 'wordArtVertRtl' | 'mongolianVert';
|
|
1258
|
+
/** Body column count (`a:bodyPr/@numCol`). */
|
|
1259
|
+
columnCount?: number;
|
|
1260
|
+
/** Column spacing in px (`a:bodyPr/@spcCol` in EMU). */
|
|
1261
|
+
columnSpacing?: number;
|
|
1262
|
+
/** Horizontal overflow mode from `a:bodyPr/@hOverflow`. */
|
|
1263
|
+
hOverflow?: 'overflow' | 'clip';
|
|
1264
|
+
/** Vertical overflow mode from `a:bodyPr/@vertOverflow`. */
|
|
1265
|
+
vertOverflow?: 'overflow' | 'clip' | 'ellipsis';
|
|
1266
|
+
/** Body text left inset in px (`a:bodyPr/@lIns` in EMU). */
|
|
1267
|
+
bodyInsetLeft?: number;
|
|
1268
|
+
/** Body text top inset in px (`a:bodyPr/@tIns` in EMU). */
|
|
1269
|
+
bodyInsetTop?: number;
|
|
1270
|
+
/** Body text right inset in px (`a:bodyPr/@rIns` in EMU). */
|
|
1271
|
+
bodyInsetRight?: number;
|
|
1272
|
+
/** Body text bottom inset in px (`a:bodyPr/@bIns` in EMU). */
|
|
1273
|
+
bodyInsetBottom?: number;
|
|
1274
|
+
/** Paragraph spacing before in px. */
|
|
1275
|
+
paragraphSpacingBefore?: number;
|
|
1276
|
+
/** Paragraph spacing after in px. */
|
|
1277
|
+
paragraphSpacingAfter?: number;
|
|
1278
|
+
/** Line spacing multiplier (e.g. 1.2 = 120%). Used when mode is proportional (spcPct). */
|
|
1279
|
+
lineSpacing?: number;
|
|
1280
|
+
/** Exact line spacing in points (from `a:lnSpc > a:spcPts`). Takes priority over `lineSpacing` when set. */
|
|
1281
|
+
lineSpacingExactPt?: number;
|
|
1282
|
+
/** Paragraph left margin in px (`a:pPr/@marL` in EMU). */
|
|
1283
|
+
paragraphMarginLeft?: number;
|
|
1284
|
+
/** Paragraph right margin in px (`a:pPr/@marR` in EMU). */
|
|
1285
|
+
paragraphMarginRight?: number;
|
|
1286
|
+
/** Paragraph first-line indent in px (`a:pPr/@indent` in EMU). */
|
|
1287
|
+
paragraphIndent?: number;
|
|
1288
|
+
/** Tab stop positions and alignments (`a:pPr/a:tabLst/a:tab`). */
|
|
1289
|
+
tabStops?: Array<{
|
|
1290
|
+
position: number;
|
|
1291
|
+
align: 'l' | 'ctr' | 'r' | 'dec';
|
|
1292
|
+
leader?: 'none' | 'dot' | 'hyphen' | 'underscore';
|
|
1293
|
+
}>;
|
|
1294
|
+
/** Body text wrapping mode from `a:bodyPr/@wrap`. */
|
|
1295
|
+
textWrap?: 'square' | 'none';
|
|
1296
|
+
/** Preset text warp type from `a:bodyPr/a:prstTxWarp`. */
|
|
1297
|
+
textWarpPreset?: PptxTextWarpPreset;
|
|
1298
|
+
/** Primary adjustment value for text warp (from `a:prstTxWarp/a:avLst/a:gd` with name "adj").
|
|
1299
|
+
* Stored as raw OOXML 1/60000th units (e.g. 50000 = default for many presets). */
|
|
1300
|
+
textWarpAdj?: number;
|
|
1301
|
+
/** Secondary adjustment value for text warp (from `a:prstTxWarp/a:avLst/a:gd` with name "adj2").
|
|
1302
|
+
* Stored as raw OOXML 1/60000th units. */
|
|
1303
|
+
textWarpAdj2?: number;
|
|
1304
|
+
/** Text capitalization style from `a:rPr/@cap`. */
|
|
1305
|
+
textCaps?: 'all' | 'small' | 'none';
|
|
1306
|
+
/**
|
|
1307
|
+
* When true, the source authored `<a:rPr cap="none"/>` explicitly. This
|
|
1308
|
+
* differs from {@link textCaps} = `"none"` only because the writer must
|
|
1309
|
+
* preserve the explicit token rather than collapse it to omission.
|
|
1310
|
+
*/
|
|
1311
|
+
textCapsExplicitNone?: boolean;
|
|
1312
|
+
/** Symbol font family from `a:sym`. */
|
|
1313
|
+
symbolFont?: string;
|
|
1314
|
+
/** East Asian font family from `a:ea`. */
|
|
1315
|
+
eastAsiaFont?: string;
|
|
1316
|
+
/** Complex Script font family from `a:cs`. */
|
|
1317
|
+
complexScriptFont?: string;
|
|
1318
|
+
/** Text language from `a:rPr/@lang`. */
|
|
1319
|
+
language?: string;
|
|
1320
|
+
/** Hyperlink mouse-over target from `a:hlinkMouseOver`. */
|
|
1321
|
+
hyperlinkMouseOver?: string;
|
|
1322
|
+
/** Hyperlink invalidUrl attribute (`a:hlinkClick/@invalidUrl`). */
|
|
1323
|
+
hyperlinkInvalidUrl?: string;
|
|
1324
|
+
/** Hyperlink target frame (`a:hlinkClick/@tgtFrame`). */
|
|
1325
|
+
hyperlinkTargetFrame?: string;
|
|
1326
|
+
/** Whether hyperlink history is tracked (`a:hlinkClick/@history`). */
|
|
1327
|
+
hyperlinkHistory?: boolean;
|
|
1328
|
+
/** Whether hyperlink uses highlight-click effect (`a:hlinkClick/@highlightClick`). */
|
|
1329
|
+
hyperlinkHighlightClick?: boolean;
|
|
1330
|
+
/** Whether hyperlink ends a sound (`a:hlinkClick/@endSnd`). */
|
|
1331
|
+
hyperlinkEndSound?: boolean;
|
|
1332
|
+
/** Kumimoji (ideographic text combining) flag for vertical CJK text (`a:rPr/@kumimoji`). */
|
|
1333
|
+
kumimoji?: boolean;
|
|
1334
|
+
/** Normalize height flag (`a:rPr/@normalizeH`). */
|
|
1335
|
+
normalizeHeight?: boolean;
|
|
1336
|
+
/** No proofing flag (`a:rPr/@noProof`). */
|
|
1337
|
+
noProof?: boolean;
|
|
1338
|
+
/** Dirty flag indicating run has been edited (`a:rPr/@dirty`). */
|
|
1339
|
+
dirty?: boolean;
|
|
1340
|
+
/** Error flag indicating spelling error (`a:rPr/@err`). */
|
|
1341
|
+
spellingError?: boolean;
|
|
1342
|
+
/** Smart tag clean flag (`a:rPr/@smtClean`). */
|
|
1343
|
+
smartTagClean?: boolean;
|
|
1344
|
+
/** Bookmark link target (`a:rPr/@bmk`). */
|
|
1345
|
+
bookmark?: string;
|
|
1346
|
+
/** Alternative language for the run (`a:rPr/@altLang`). Populated for runs
|
|
1347
|
+
* authored in mixed-script documents (e.g. Asian/Latin combined). */
|
|
1348
|
+
altLanguage?: string;
|
|
1349
|
+
/** SmartTag (Office grammar tag) GUID id (`a:rPr/@smtId`). Round-tripped
|
|
1350
|
+
* verbatim — the engine doesn't interpret it. */
|
|
1351
|
+
smartTagId?: number;
|
|
1352
|
+
/** Latin font PANOSE classification string from `a:rPr > a:latin/@panose`. */
|
|
1353
|
+
latinFontPanose?: string;
|
|
1354
|
+
/** Latin font pitch + family flag from `a:rPr > a:latin/@pitchFamily`. */
|
|
1355
|
+
latinFontPitchFamily?: number;
|
|
1356
|
+
/** Latin font character set id from `a:rPr > a:latin/@charset`. */
|
|
1357
|
+
latinFontCharset?: number;
|
|
1358
|
+
/** East-Asian font PANOSE from `a:rPr > a:ea/@panose`. */
|
|
1359
|
+
eastAsiaFontPanose?: string;
|
|
1360
|
+
/** East-Asian font pitch + family flag from `a:rPr > a:ea/@pitchFamily`. */
|
|
1361
|
+
eastAsiaFontPitchFamily?: number;
|
|
1362
|
+
/** East-Asian font character set id from `a:rPr > a:ea/@charset`. */
|
|
1363
|
+
eastAsiaFontCharset?: number;
|
|
1364
|
+
/** Complex-script font PANOSE from `a:rPr > a:cs/@panose`. */
|
|
1365
|
+
complexScriptFontPanose?: string;
|
|
1366
|
+
/** Complex-script font pitch + family flag from `a:rPr > a:cs/@pitchFamily`. */
|
|
1367
|
+
complexScriptFontPitchFamily?: number;
|
|
1368
|
+
/** Complex-script font character set id from `a:rPr > a:cs/@charset`. */
|
|
1369
|
+
complexScriptFontCharset?: number;
|
|
1370
|
+
/** Symbol-font PANOSE from `a:rPr > a:sym/@panose`. */
|
|
1371
|
+
symbolFontPanose?: string;
|
|
1372
|
+
/** Symbol-font pitch + family flag from `a:rPr > a:sym/@pitchFamily`. */
|
|
1373
|
+
symbolFontPitchFamily?: number;
|
|
1374
|
+
/** Symbol-font character set id from `a:rPr > a:sym/@charset`. */
|
|
1375
|
+
symbolFontCharset?: number;
|
|
1376
|
+
/** Paragraph list type for toggling bullet / numbered lists via the toolbar.
|
|
1377
|
+
* - `'bullet'` — character bullet (default "•")
|
|
1378
|
+
* - `'numbered'` — auto-numbered list (arabicPeriod)
|
|
1379
|
+
* - `'none'` — explicitly no list
|
|
1380
|
+
*/
|
|
1381
|
+
listType?: 'bullet' | 'numbered' | 'none';
|
|
1382
|
+
/** Default tab size in px (`a:pPr/@defTabSz` in EMU). */
|
|
1383
|
+
defaultTabSize?: number;
|
|
1384
|
+
/** East Asian line break flag (`a:pPr/@eaLnBrk`). */
|
|
1385
|
+
eaLineBreak?: boolean;
|
|
1386
|
+
/** Latin line break flag (`a:pPr/@latinLnBrk`). */
|
|
1387
|
+
latinLineBreak?: boolean;
|
|
1388
|
+
/** Font alignment (`a:pPr/@fontAlgn`): 'auto' | 'base' | 'ctr' | 't' | 'b'. */
|
|
1389
|
+
fontAlignment?: string;
|
|
1390
|
+
/** Hanging punctuation flag (`a:pPr/@hangingPunct`). */
|
|
1391
|
+
hangingPunctuation?: boolean;
|
|
1392
|
+
/** Whether to space first and last paragraph from body edges (`a:bodyPr/@spcFirstLastPara`). */
|
|
1393
|
+
spaceFirstLastParagraph?: boolean;
|
|
1394
|
+
/** Right-to-left column flow (`a:bodyPr/@rtlCol`). */
|
|
1395
|
+
rtlColumns?: boolean;
|
|
1396
|
+
/** Whether text originates from WordArt (`a:bodyPr/@fromWordArt`). */
|
|
1397
|
+
fromWordArt?: boolean;
|
|
1398
|
+
/** Whether text anchoring is centered (`a:bodyPr/@anchorCtr`). */
|
|
1399
|
+
anchorCenter?: boolean;
|
|
1400
|
+
/** Force anti-aliasing (`a:bodyPr/@forceAA`). */
|
|
1401
|
+
forceAntiAlias?: boolean;
|
|
1402
|
+
/** Upright text in 3D views (`a:bodyPr/@upright`). */
|
|
1403
|
+
upright?: boolean;
|
|
1404
|
+
/** Compatible line spacing flag (`a:bodyPr/@compatLnSpc`). */
|
|
1405
|
+
compatibleLineSpacing?: boolean;
|
|
1406
|
+
/**
|
|
1407
|
+
* Text body rotation in **degrees** (`a:bodyPr/@rot`).
|
|
1408
|
+
*
|
|
1409
|
+
* OOXML stores the value as 60000ths of a degree. Positive values rotate
|
|
1410
|
+
* the body clockwise. When undefined, the attribute is omitted on save
|
|
1411
|
+
* (PowerPoint treats absent `rot` as inherit/none).
|
|
1412
|
+
*/
|
|
1413
|
+
textBodyRotation?: number;
|
|
1414
|
+
/** Text shadow colour as hex string (`a:outerShdw`). */
|
|
1415
|
+
textShadowColor?: string;
|
|
1416
|
+
/** Text shadow blur radius in px. */
|
|
1417
|
+
textShadowBlur?: number;
|
|
1418
|
+
/** Text shadow horizontal offset in px. */
|
|
1419
|
+
textShadowOffsetX?: number;
|
|
1420
|
+
/** Text shadow vertical offset in px. */
|
|
1421
|
+
textShadowOffsetY?: number;
|
|
1422
|
+
/** Text shadow opacity (0-1). */
|
|
1423
|
+
textShadowOpacity?: number;
|
|
1424
|
+
/** Text inner shadow colour (`a:innerShdw`). */
|
|
1425
|
+
textInnerShadowColor?: string;
|
|
1426
|
+
/** Text inner shadow opacity (0-1). */
|
|
1427
|
+
textInnerShadowOpacity?: number;
|
|
1428
|
+
/** Text inner shadow blur radius in px. */
|
|
1429
|
+
textInnerShadowBlur?: number;
|
|
1430
|
+
/** Text inner shadow horizontal offset in px. */
|
|
1431
|
+
textInnerShadowOffsetX?: number;
|
|
1432
|
+
/** Text inner shadow vertical offset in px. */
|
|
1433
|
+
textInnerShadowOffsetY?: number;
|
|
1434
|
+
/** Preset shadow type from `a:prstShdw/@prst` (e.g. "shdw1"..."shdw20"). */
|
|
1435
|
+
textPresetShadowName?: string;
|
|
1436
|
+
/** Preset shadow colour as hex string. */
|
|
1437
|
+
textPresetShadowColor?: string;
|
|
1438
|
+
/** Preset shadow opacity (0-1). */
|
|
1439
|
+
textPresetShadowOpacity?: number;
|
|
1440
|
+
/** Preset shadow distance in px. */
|
|
1441
|
+
textPresetShadowDistance?: number;
|
|
1442
|
+
/** Preset shadow direction in degrees. */
|
|
1443
|
+
textPresetShadowDirection?: number;
|
|
1444
|
+
/** Text blur effect radius in px (`a:blur`). */
|
|
1445
|
+
textBlurRadius?: number;
|
|
1446
|
+
/** Text alpha modulation fixed (0-100) from `a:alphaModFix`. */
|
|
1447
|
+
textAlphaModFix?: number;
|
|
1448
|
+
/** Text alpha modulation from `a:alphaMod` (0-100 percentage). */
|
|
1449
|
+
textAlphaMod?: number;
|
|
1450
|
+
/** Text hue shift in degrees from `a:hsl/@hue`. */
|
|
1451
|
+
textHslHue?: number;
|
|
1452
|
+
/** Text saturation adjustment from `a:hsl/@sat`. */
|
|
1453
|
+
textHslSaturation?: number;
|
|
1454
|
+
/** Text luminance adjustment from `a:hsl/@lum`. */
|
|
1455
|
+
textHslLuminance?: number;
|
|
1456
|
+
/** Text colour change from colour as hex string (`a:clrChange`). */
|
|
1457
|
+
textClrChangeFrom?: string;
|
|
1458
|
+
/** Text colour change to colour as hex string. */
|
|
1459
|
+
textClrChangeTo?: string;
|
|
1460
|
+
/** Text duotone colour pair (`a:duotone`). */
|
|
1461
|
+
textDuotone?: {
|
|
1462
|
+
color1: string;
|
|
1463
|
+
color2: string;
|
|
1464
|
+
};
|
|
1465
|
+
/** Text glow colour as hex string (`a:glow`). */
|
|
1466
|
+
textGlowColor?: string;
|
|
1467
|
+
/** Text glow radius in px. */
|
|
1468
|
+
textGlowRadius?: number;
|
|
1469
|
+
/** Text glow opacity (0-1). */
|
|
1470
|
+
textGlowOpacity?: number;
|
|
1471
|
+
/** Text reflection enabled flag. */
|
|
1472
|
+
textReflection?: boolean;
|
|
1473
|
+
/** Text reflection blur radius in px. */
|
|
1474
|
+
textReflectionBlur?: number;
|
|
1475
|
+
/** Text reflection start opacity (0-1). */
|
|
1476
|
+
textReflectionStartOpacity?: number;
|
|
1477
|
+
/** Text reflection end opacity (0-1). */
|
|
1478
|
+
textReflectionEndOpacity?: number;
|
|
1479
|
+
/** Text reflection offset distance in px. */
|
|
1480
|
+
textReflectionOffset?: number;
|
|
1481
|
+
/** 3D extrusion/bevel settings on the text body. */
|
|
1482
|
+
text3d?: Text3DStyle;
|
|
1483
|
+
/** 3D scene (camera + light rig) settings on the text body (`a:bodyPr/a:scene3d`). */
|
|
1484
|
+
textBodyScene3d?: Pptx3DScene;
|
|
1485
|
+
/**
|
|
1486
|
+
* Raw `<a:extLst>` subtree captured from `<a:bodyPr>`. Preserved verbatim so
|
|
1487
|
+
* authored extensions (e.g. content placeholders, custom application data)
|
|
1488
|
+
* survive a round-trip even though the engine doesn't interpret them.
|
|
1489
|
+
*/
|
|
1490
|
+
bodyPropertiesExtLstXml?: XmlObject;
|
|
1491
|
+
/**
|
|
1492
|
+
* Raw `<a:extLst>` subtree captured from `<a:pPr>`. Only meaningful on the
|
|
1493
|
+
* paragraph-level style (paragraphs propagate this via the first segment).
|
|
1494
|
+
*/
|
|
1495
|
+
paragraphPropertiesExtLstXml?: XmlObject;
|
|
1496
|
+
/**
|
|
1497
|
+
* Raw `<a:extLst>` subtree captured from `<a:rPr>`. Persisted verbatim on
|
|
1498
|
+
* save when present — covers run-level extensions the typed model doesn't
|
|
1499
|
+
* model (e.g. `a14:hiddenFill` and similar).
|
|
1500
|
+
*/
|
|
1501
|
+
runPropertiesExtLstXml?: XmlObject;
|
|
1502
|
+
/**
|
|
1503
|
+
* Raw `<a:defRPr>` XML node captured from `<a:pPr>`. The schema permits
|
|
1504
|
+
* `defRPr` directly inside `pPr` so that paragraph defaults can specify the
|
|
1505
|
+
* end-paragraph run formatting; previously this was dropped on save. We
|
|
1506
|
+
* persist the parsed XML object so it round-trips verbatim.
|
|
1507
|
+
*
|
|
1508
|
+
* Only meaningful on the *first* segment of each paragraph (matches the
|
|
1509
|
+
* convention used for {@link bulletInfo} / {@link endParaRunProperties}).
|
|
1510
|
+
*/
|
|
1511
|
+
paragraphDefaultRunPropertiesXml?: XmlObject;
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Structured bullet metadata attached to the first {@link TextSegment}
|
|
1515
|
+
* of each paragraph.
|
|
1516
|
+
*
|
|
1517
|
+
* Describes how the paragraph bullet should render: character bullets
|
|
1518
|
+
* (`char`), auto-numbered lists (`autoNumType`), or picture bullets
|
|
1519
|
+
* (`imageRelId` / `imageDataUrl`). Set `none: true` when `a:buNone`
|
|
1520
|
+
* explicitly suppresses the bullet.
|
|
1521
|
+
*
|
|
1522
|
+
* @example
|
|
1523
|
+
* ```ts
|
|
1524
|
+
* // Simple character bullet:
|
|
1525
|
+
* const bullet: BulletInfo = { char: "•", color: "#333333" };
|
|
1526
|
+
*
|
|
1527
|
+
* // Auto-numbered list starting at 1:
|
|
1528
|
+
* const numbered: BulletInfo = {
|
|
1529
|
+
* autoNumType: "arabicPeriod",
|
|
1530
|
+
* autoNumStartAt: 1,
|
|
1531
|
+
* };
|
|
1532
|
+
* // => { char: "•", color: "#333333" } and { autoNumType: "arabicPeriod", autoNumStartAt: 1 }
|
|
1533
|
+
* ```
|
|
1534
|
+
*/
|
|
1535
|
+
interface BulletInfo {
|
|
1536
|
+
/** Bullet character (e.g. "•", "-", "»") from `a:buChar`. */
|
|
1537
|
+
char?: string;
|
|
1538
|
+
/** Auto-numbering type (e.g. "arabicPeriod", "romanUcPeriod") from `a:buAutoNum`. */
|
|
1539
|
+
autoNumType?: string;
|
|
1540
|
+
/** Auto-numbering start value. */
|
|
1541
|
+
autoNumStartAt?: number;
|
|
1542
|
+
/** Zero-based paragraph index within the text body (for auto-numbering). */
|
|
1543
|
+
paragraphIndex?: number;
|
|
1544
|
+
/** Bullet font family from `a:buFont`. */
|
|
1545
|
+
fontFamily?: string;
|
|
1546
|
+
/** Bullet size as percentage of text font size from `a:buSzPct`. */
|
|
1547
|
+
sizePercent?: number;
|
|
1548
|
+
/** Bullet size in points from `a:buSzPts`. */
|
|
1549
|
+
sizePts?: number;
|
|
1550
|
+
/** Bullet color as hex string from `a:buClr`. */
|
|
1551
|
+
color?: string;
|
|
1552
|
+
/**
|
|
1553
|
+
* Raw colour-choice XML captured from `<a:buClr>` so that themed bullets
|
|
1554
|
+
* (`a:schemeClr`, `a:sysClr`, `a:prstClr`) round-trip with their original
|
|
1555
|
+
* identity rather than being flattened to `<a:srgbClr/>` on save.
|
|
1556
|
+
*/
|
|
1557
|
+
colorXml?: XmlObject;
|
|
1558
|
+
/** True when `a:buNone` explicitly suppresses bullets. */
|
|
1559
|
+
none?: boolean;
|
|
1560
|
+
/** Picture bullet: relationship ID from `a:buBlip` → `a:blip[@r:embed]`. */
|
|
1561
|
+
imageRelId?: string;
|
|
1562
|
+
/** Picture bullet: data URL of the embedded image. */
|
|
1563
|
+
imageDataUrl?: string;
|
|
1564
|
+
/**
|
|
1565
|
+
* Raw `<a:buBlip>` XML captured at parse time. Carries the full blipFill
|
|
1566
|
+
* subtree (`a:tile`, `a:stretch`, `a:srcRect`, `a:blip > a:extLst`) so the
|
|
1567
|
+
* writer can emit the complete original definition rather than the bare
|
|
1568
|
+
* `a:blip[@r:embed]` mapping. When set, the writer prefers it over
|
|
1569
|
+
* {@link imageRelId} for emission.
|
|
1570
|
+
*/
|
|
1571
|
+
imageBlipFillXml?: XmlObject;
|
|
1572
|
+
/** When true, `<a:buFontTx/>` was specified — inherit the bullet font from
|
|
1573
|
+
* the run text, not from a buFont declaration. */
|
|
1574
|
+
fontInherit?: boolean;
|
|
1575
|
+
/** When true, `<a:buClrTx/>` was specified — inherit the bullet colour from
|
|
1576
|
+
* the run text. */
|
|
1577
|
+
colorInherit?: boolean;
|
|
1578
|
+
/** When true, `<a:buSzTx/>` was specified — inherit the bullet size from
|
|
1579
|
+
* the run text font size. */
|
|
1580
|
+
sizeInherit?: boolean;
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* A single text run within a paragraph.
|
|
1584
|
+
*
|
|
1585
|
+
* A text body is decomposed into an array of `TextSegment` objects,
|
|
1586
|
+
* each with its own style. Paragraph breaks are represented as
|
|
1587
|
+
* segments with `isParagraphBreak: true`.
|
|
1588
|
+
*
|
|
1589
|
+
* @example
|
|
1590
|
+
* ```ts
|
|
1591
|
+
* const segments: TextSegment[] = [
|
|
1592
|
+
* { text: "Bold intro ", style: { bold: true, fontSize: 16 } },
|
|
1593
|
+
* { text: "and normal text.", style: { fontSize: 16 } },
|
|
1594
|
+
* { text: "", style: {}, isParagraphBreak: true },
|
|
1595
|
+
* { text: "Second paragraph.", style: { fontSize: 14 } },
|
|
1596
|
+
* ];
|
|
1597
|
+
* // => 4 segments: 2 styled runs, 1 paragraph break, 1 normal run
|
|
1598
|
+
* ```
|
|
1599
|
+
*/
|
|
1600
|
+
interface TextSegment {
|
|
1601
|
+
text: string;
|
|
1602
|
+
style: TextStyle;
|
|
1603
|
+
/** When this segment originated from an `a:fld` element, stores the field type (e.g. "slidenum", "datetime"). */
|
|
1604
|
+
fieldType?: string;
|
|
1605
|
+
/** When this segment originated from an `a:fld` element, stores the field GUID. */
|
|
1606
|
+
fieldGuid?: string;
|
|
1607
|
+
/**
|
|
1608
|
+
* Original attribute name used to author the field GUID — `'uuid'` for the
|
|
1609
|
+
* `a:fld/@uuid` form authored by some legacy producers, `'id'` for the
|
|
1610
|
+
* canonical `a:fld/@id` form. Preserved so the writer round-trips whichever
|
|
1611
|
+
* spelling the source used (PowerPoint accepts both). Defaults to `'id'`
|
|
1612
|
+
* on save when undefined.
|
|
1613
|
+
*/
|
|
1614
|
+
fieldGuidAttr?: 'uuid' | 'id';
|
|
1615
|
+
/**
|
|
1616
|
+
* Raw per-field paragraph properties (`a:fld > a:pPr`). The schema permits
|
|
1617
|
+
* `pPr` inside an `a:fld` so the field can carry its own paragraph-level
|
|
1618
|
+
* formatting; preserved verbatim on save when present.
|
|
1619
|
+
*/
|
|
1620
|
+
fieldParagraphPropertiesXml?: XmlObject;
|
|
1621
|
+
/** Raw OMML XML node for equation segments (from `a14:m` / `m:oMathPara`). */
|
|
1622
|
+
equationXml?: Record<string, unknown>;
|
|
1623
|
+
/**
|
|
1624
|
+
* Optional equation number for numbered equations (e.g. "(1)", "(2.3)").
|
|
1625
|
+
* When present, the equation is rendered centered with the number right-aligned.
|
|
1626
|
+
*/
|
|
1627
|
+
equationNumber?: string;
|
|
1628
|
+
/** Whether this segment represents a paragraph break rather than renderable text. */
|
|
1629
|
+
isParagraphBreak?: boolean;
|
|
1630
|
+
/**
|
|
1631
|
+
* Whether this segment represents a soft line break (`a:br`) rather than
|
|
1632
|
+
* a paragraph terminator. Soft line breaks remain inside the same paragraph
|
|
1633
|
+
* but force a line wrap and may carry their own run properties.
|
|
1634
|
+
*
|
|
1635
|
+
* The renderer should treat the segment text as `"\n"` when present.
|
|
1636
|
+
*/
|
|
1637
|
+
isLineBreak?: true;
|
|
1638
|
+
/**
|
|
1639
|
+
* Raw `a:rPr` XML for an `a:br` (soft line break) segment, captured verbatim
|
|
1640
|
+
* during parse so the writer can re-emit attributes/colours/fonts that the
|
|
1641
|
+
* typed model doesn't represent. Only meaningful when {@link isLineBreak}
|
|
1642
|
+
* is `true`.
|
|
1643
|
+
*/
|
|
1644
|
+
breakRunProperties?: Record<string, unknown>;
|
|
1645
|
+
/** Structured bullet info for the first segment of a paragraph. */
|
|
1646
|
+
bulletInfo?: BulletInfo;
|
|
1647
|
+
/**
|
|
1648
|
+
* Outline level for the paragraph this segment starts (`a:p/@lvl`).
|
|
1649
|
+
*
|
|
1650
|
+
* Only meaningful on the first segment of a paragraph (matching the
|
|
1651
|
+
* convention used for {@link bulletInfo}). Stored as the raw OOXML
|
|
1652
|
+
* value (0 = top level, 1-8 = nested) and serialised back when non-zero.
|
|
1653
|
+
*/
|
|
1654
|
+
paragraphLevel?: number;
|
|
1655
|
+
/**
|
|
1656
|
+
* Raw `a:endParaRPr` XML node for the paragraph this segment starts.
|
|
1657
|
+
*
|
|
1658
|
+
* Captured verbatim on parse so attributes and child colours/fonts that
|
|
1659
|
+
* the typed model doesn't represent survive a round-trip. Only meaningful
|
|
1660
|
+
* on the first segment of a paragraph.
|
|
1661
|
+
*/
|
|
1662
|
+
endParaRunProperties?: Record<string, unknown>;
|
|
1663
|
+
/**
|
|
1664
|
+
* Phonetic annotation text from `a:ruby > a:rt` (e.g. furigana, pinyin).
|
|
1665
|
+
* When present, the renderer should wrap the base text with an HTML `<ruby>` tag.
|
|
1666
|
+
*/
|
|
1667
|
+
rubyText?: string;
|
|
1668
|
+
/**
|
|
1669
|
+
* Ruby text alignment from `a:rubyPr > @val` attribute.
|
|
1670
|
+
* Values: "ctr" (center), "l" (left), "r" (right), "dist" (distribute), "distCat", "distLetter".
|
|
1671
|
+
* @default "ctr"
|
|
1672
|
+
*/
|
|
1673
|
+
rubyAlignment?: string;
|
|
1674
|
+
/**
|
|
1675
|
+
* Ruby text font size as a percentage of the base text font size
|
|
1676
|
+
* from `a:rubyPr/@hps` (half-point size) or inferred from rt run font size.
|
|
1677
|
+
* Stored in **points** for consistency with `TextStyle.fontSize`.
|
|
1678
|
+
*/
|
|
1679
|
+
rubyFontSize?: number;
|
|
1680
|
+
/**
|
|
1681
|
+
* Style for the ruby (phonetic) text run, parsed from `a:rt > a:r > a:rPr`.
|
|
1682
|
+
* Used by the renderer to apply font family, colour, etc. to the `<rt>` element.
|
|
1683
|
+
*/
|
|
1684
|
+
rubyStyle?: TextStyle;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
/**
|
|
1688
|
+
* Base and mixin interfaces for all PPTX slide elements, plus
|
|
1689
|
+
* placeholder inheritance types.
|
|
1690
|
+
*
|
|
1691
|
+
* Every concrete element variant (text, shape, image …) extends
|
|
1692
|
+
* {@link PptxElementBase}. Text-bearing elements also mix in
|
|
1693
|
+
* {@link PptxTextProperties}, and shapes / connectors / images add
|
|
1694
|
+
* {@link PptxShapeProperties}.
|
|
1695
|
+
*
|
|
1696
|
+
* @module pptx-types/element-base
|
|
1697
|
+
*/
|
|
1698
|
+
|
|
1699
|
+
/**
|
|
1700
|
+
* Properties shared by **every** element on a slide.
|
|
1701
|
+
*
|
|
1702
|
+
* Position and size are in pixels (converted from EMU at parse time).
|
|
1703
|
+
* Optional properties apply to subsets of elements or may be absent in
|
|
1704
|
+
* the original OOXML.
|
|
1705
|
+
*
|
|
1706
|
+
* @example
|
|
1707
|
+
* ```ts
|
|
1708
|
+
* const base: PptxElementBase = {
|
|
1709
|
+
* id: "el_001",
|
|
1710
|
+
* x: 100, y: 50,
|
|
1711
|
+
* width: 400, height: 200,
|
|
1712
|
+
* rotation: 15,
|
|
1713
|
+
* opacity: 0.9,
|
|
1714
|
+
* };
|
|
1715
|
+
* // => satisfies PptxElementBase
|
|
1716
|
+
* ```
|
|
1717
|
+
*/
|
|
1718
|
+
interface PptxElementBase {
|
|
1719
|
+
id: string;
|
|
1720
|
+
/**
|
|
1721
|
+
* The shape's native OOXML id from `p:cNvPr/@id` (an unsigned integer, as a
|
|
1722
|
+
* string), captured on load. Distinct from {@link id}, which is a synthetic
|
|
1723
|
+
* positional identity (`${slidePath}-shape-${index}`) the loader assigns for
|
|
1724
|
+
* selection / undo / template tracking. Animations target shapes by this
|
|
1725
|
+
* native id (`p:spTgt/@spid`), so it is the stable key used to reconcile an
|
|
1726
|
+
* animation to the element it animates across a save/reload round trip.
|
|
1727
|
+
* Absent on SDK-created elements until one is minted at save time.
|
|
1728
|
+
*/
|
|
1729
|
+
shapeId?: string;
|
|
1730
|
+
/** Element name from `cNvPr/@name`. Used for morph transition matching via the `!!` naming convention. */
|
|
1731
|
+
name?: string;
|
|
1732
|
+
x: number;
|
|
1733
|
+
y: number;
|
|
1734
|
+
width: number;
|
|
1735
|
+
height: number;
|
|
1736
|
+
rotation?: number;
|
|
1737
|
+
/** Skew along the X axis in degrees (parsed from `@_skewX` in 1/60000ths of a degree). */
|
|
1738
|
+
skewX?: number;
|
|
1739
|
+
/** Skew along the Y axis in degrees (parsed from `@_skewY` in 1/60000ths of a degree). */
|
|
1740
|
+
skewY?: number;
|
|
1741
|
+
flipHorizontal?: boolean;
|
|
1742
|
+
flipVertical?: boolean;
|
|
1743
|
+
/** Whether this element is hidden (used by the Elements Panel visibility toggle). */
|
|
1744
|
+
hidden?: boolean;
|
|
1745
|
+
/** Element-level opacity (0-1). */
|
|
1746
|
+
opacity?: number;
|
|
1747
|
+
rawXml?: XmlObject;
|
|
1748
|
+
/** Shape-level click action (from `a:hlinkClick` on `p:cNvPr`). */
|
|
1749
|
+
actionClick?: PptxAction;
|
|
1750
|
+
/** Shape-level hover action (from `a:hlinkHover` on `p:cNvPr`). */
|
|
1751
|
+
actionHover?: PptxAction;
|
|
1752
|
+
/** Shape lock attributes parsed from `p:cNvSpPr/a:spLocks`. */
|
|
1753
|
+
locks?: PptxShapeLocks;
|
|
1754
|
+
/**
|
|
1755
|
+
* Opaque `<a:ext>` children captured from the shape's `<a:extLst>` whose
|
|
1756
|
+
* URI is not recognised by a typed extractor (hidden fill/line, image
|
|
1757
|
+
* effects, …). Preserved verbatim and re-emitted on save so unknown
|
|
1758
|
+
* vendor extensions survive a round-trip.
|
|
1759
|
+
*
|
|
1760
|
+
* Mirrors the existing `effectDagXml` / `endParaRunProperties` raw-XML
|
|
1761
|
+
* preservation pattern.
|
|
1762
|
+
*/
|
|
1763
|
+
extLstXml?: XmlObject[];
|
|
1764
|
+
}
|
|
1765
|
+
/**
|
|
1766
|
+
* Text content mixin — present on text boxes and shapes.
|
|
1767
|
+
*
|
|
1768
|
+
* Shapes can contain text overlaid on the shape geometry, so both
|
|
1769
|
+
* `TextPptxElement` and `ShapePptxElement` extend this interface.
|
|
1770
|
+
*
|
|
1771
|
+
* @example
|
|
1772
|
+
* ```ts
|
|
1773
|
+
* const props: PptxTextProperties = {
|
|
1774
|
+
* text: "Hello World",
|
|
1775
|
+
* textStyle: { fontSize: 24, bold: true, color: "#333333" },
|
|
1776
|
+
* };
|
|
1777
|
+
* // => satisfies PptxTextProperties
|
|
1778
|
+
* ```
|
|
1779
|
+
*/
|
|
1780
|
+
interface PptxTextProperties {
|
|
1781
|
+
text?: string;
|
|
1782
|
+
textStyle?: TextStyle;
|
|
1783
|
+
/** Rich text segments with individual styling. */
|
|
1784
|
+
textSegments?: TextSegment[];
|
|
1785
|
+
/** Per-paragraph indentation (marginLeft, indent) for multi-level bullet support. */
|
|
1786
|
+
paragraphIndents?: Array<{
|
|
1787
|
+
marginLeft?: number;
|
|
1788
|
+
indent?: number;
|
|
1789
|
+
}>;
|
|
1790
|
+
/** Placeholder prompt text inherited from layout/master (e.g. "Click to add title"). Shown as a greyed-out hint when the shape has no user-entered text. */
|
|
1791
|
+
promptText?: string;
|
|
1792
|
+
/** Linked text box chain ID from `a:bodyPr > a:linkedTxbx/@id` or `a:txbx > a:linkedTxbx/@id`. Text overflows from one linked frame to the next. */
|
|
1793
|
+
linkedTxbxId?: number;
|
|
1794
|
+
/** Sequence number within a linked text box chain (0-based). */
|
|
1795
|
+
linkedTxbxSeq?: number;
|
|
1796
|
+
}
|
|
1797
|
+
/**
|
|
1798
|
+
* Shape styling & geometry mixin — present on shapes, connectors, and images.
|
|
1799
|
+
*
|
|
1800
|
+
* @example
|
|
1801
|
+
* ```ts
|
|
1802
|
+
* const props: PptxShapeProperties = {
|
|
1803
|
+
* shapeType: "roundRect",
|
|
1804
|
+
* shapeStyle: { fillColor: "#0055AA", strokeWidth: 2 },
|
|
1805
|
+
* shapeAdjustments: { adj: 16667 },
|
|
1806
|
+
* };
|
|
1807
|
+
* // => satisfies PptxShapeProperties
|
|
1808
|
+
* ```
|
|
1809
|
+
*/
|
|
1810
|
+
interface PptxShapeProperties {
|
|
1811
|
+
shapeStyle?: ShapeStyle;
|
|
1812
|
+
/** Preset geometry name, e.g. "rect", "ellipse", "roundRect". */
|
|
1813
|
+
shapeType?: string;
|
|
1814
|
+
/** Geometry adjustment values, e.g. `{ adj: 16667 }`. */
|
|
1815
|
+
shapeAdjustments?: Record<string, number>;
|
|
1816
|
+
/** Adjustment handles for interactive shape modification (yellow diamond handles). */
|
|
1817
|
+
adjustmentHandles?: GeometryAdjustmentHandle[];
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
/**
|
|
1821
|
+
* Chart types: chart categories, series data, style metadata, data tables,
|
|
1822
|
+
* trendlines, error bars, and the composite `PptxChartData`.
|
|
1823
|
+
*
|
|
1824
|
+
* @module pptx-types/chart
|
|
1825
|
+
*/
|
|
1826
|
+
/**
|
|
1827
|
+
* Supported chart type discriminators.
|
|
1828
|
+
*
|
|
1829
|
+
* @example
|
|
1830
|
+
* ```ts
|
|
1831
|
+
* const type: PptxChartType = "bar";
|
|
1832
|
+
* // => "bar" — one of: "bar" | "line" | "pie" | "doughnut" | "area" | "scatter" | …
|
|
1833
|
+
* ```
|
|
1834
|
+
*/
|
|
1835
|
+
type PptxChartType = 'bar' | 'line' | 'pie' | 'ofPie' | 'doughnut' | 'area' | 'scatter' | 'bubble' | 'radar' | 'stock' | 'bar3D' | 'line3D' | 'pie3D' | 'area3D' | 'surface' | 'histogram' | 'waterfall' | 'funnel' | 'treemap' | 'sunburst' | 'boxWhisker' | 'regionMap' | 'combo' | 'unknown';
|
|
1836
|
+
/**
|
|
1837
|
+
* Supported trendline regression types.
|
|
1838
|
+
*
|
|
1839
|
+
* @example
|
|
1840
|
+
* ```ts
|
|
1841
|
+
* const type: PptxChartTrendlineType = "linear";
|
|
1842
|
+
* // => "linear" — one of: "linear" | "exponential" | "logarithmic" | "polynomial" | "power" | "movingAvg"
|
|
1843
|
+
* ```
|
|
1844
|
+
*/
|
|
1845
|
+
type PptxChartTrendlineType = 'linear' | 'exponential' | 'logarithmic' | 'polynomial' | 'power' | 'movingAvg';
|
|
1846
|
+
/**
|
|
1847
|
+
* Configuration for a chart trendline (regression line).
|
|
1848
|
+
*
|
|
1849
|
+
* @example
|
|
1850
|
+
* ```ts
|
|
1851
|
+
* const trendline: PptxChartTrendline = {
|
|
1852
|
+
* trendlineType: "linear",
|
|
1853
|
+
* displayEq: true,
|
|
1854
|
+
* displayRSq: true,
|
|
1855
|
+
* color: "#FF0000",
|
|
1856
|
+
* };
|
|
1857
|
+
* // => satisfies PptxChartTrendline
|
|
1858
|
+
* ```
|
|
1859
|
+
*/
|
|
1860
|
+
interface PptxChartTrendline {
|
|
1861
|
+
trendlineType: PptxChartTrendlineType;
|
|
1862
|
+
order?: number;
|
|
1863
|
+
period?: number;
|
|
1864
|
+
forward?: number;
|
|
1865
|
+
backward?: number;
|
|
1866
|
+
intercept?: number;
|
|
1867
|
+
displayRSq?: boolean;
|
|
1868
|
+
displayEq?: boolean;
|
|
1869
|
+
color?: string;
|
|
1870
|
+
}
|
|
1871
|
+
/** Error-bar direction axis. */
|
|
1872
|
+
type PptxChartErrBarDir = 'x' | 'y';
|
|
1873
|
+
/** Error-bar display type (both sides, negative only, or positive only). */
|
|
1874
|
+
type PptxChartErrBarType = 'both' | 'minus' | 'plus';
|
|
1875
|
+
/**
|
|
1876
|
+
* How the error-bar value is calculated.
|
|
1877
|
+
*
|
|
1878
|
+
* @example
|
|
1879
|
+
* ```ts
|
|
1880
|
+
* const valType: PptxChartErrValType = "percentage";
|
|
1881
|
+
* // => "percentage" — one of: "cust" | "fixedVal" | "percentage" | "stdDev" | "stdErr"
|
|
1882
|
+
* ```
|
|
1883
|
+
*/
|
|
1884
|
+
type PptxChartErrValType = 'cust' | 'fixedVal' | 'percentage' | 'stdDev' | 'stdErr';
|
|
1885
|
+
/**
|
|
1886
|
+
* Error bars for a chart series.
|
|
1887
|
+
*
|
|
1888
|
+
* @example
|
|
1889
|
+
* ```ts
|
|
1890
|
+
* const bars: PptxChartErrBars = {
|
|
1891
|
+
* direction: "y",
|
|
1892
|
+
* barType: "both",
|
|
1893
|
+
* valType: "percentage",
|
|
1894
|
+
* val: 5,
|
|
1895
|
+
* };
|
|
1896
|
+
* // => satisfies PptxChartErrBars
|
|
1897
|
+
* ```
|
|
1898
|
+
*/
|
|
1899
|
+
interface PptxChartErrBars {
|
|
1900
|
+
direction: PptxChartErrBarDir;
|
|
1901
|
+
barType: PptxChartErrBarType;
|
|
1902
|
+
valType: PptxChartErrValType;
|
|
1903
|
+
val?: number;
|
|
1904
|
+
customPlus?: number[];
|
|
1905
|
+
customMinus?: number[];
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Visibility flags for the chart data table (axes + legend keys).
|
|
1909
|
+
*
|
|
1910
|
+
* @example
|
|
1911
|
+
* ```ts
|
|
1912
|
+
* const dt: PptxChartDataTable = {
|
|
1913
|
+
* showHorzBorder: true,
|
|
1914
|
+
* showVertBorder: true,
|
|
1915
|
+
* showOutline: true,
|
|
1916
|
+
* showKeys: true,
|
|
1917
|
+
* };
|
|
1918
|
+
* // => satisfies PptxChartDataTable
|
|
1919
|
+
* ```
|
|
1920
|
+
*/
|
|
1921
|
+
interface PptxChartDataTable {
|
|
1922
|
+
showHorzBorder?: boolean;
|
|
1923
|
+
showVertBorder?: boolean;
|
|
1924
|
+
showOutline?: boolean;
|
|
1925
|
+
showKeys?: boolean;
|
|
1926
|
+
}
|
|
1927
|
+
/**
|
|
1928
|
+
* Line appearance for chart helper lines (drop lines, hi-low lines).
|
|
1929
|
+
*
|
|
1930
|
+
* @example
|
|
1931
|
+
* ```ts
|
|
1932
|
+
* const style: PptxChartLineStyle = {
|
|
1933
|
+
* color: "#AAAAAA",
|
|
1934
|
+
* width: 1,
|
|
1935
|
+
* dashStyle: "dash",
|
|
1936
|
+
* };
|
|
1937
|
+
* // => satisfies PptxChartLineStyle
|
|
1938
|
+
* ```
|
|
1939
|
+
*/
|
|
1940
|
+
interface PptxChartLineStyle {
|
|
1941
|
+
color?: string;
|
|
1942
|
+
width?: number;
|
|
1943
|
+
dashStyle?: string;
|
|
1944
|
+
}
|
|
1945
|
+
/** Marker symbol types for line/scatter chart data points. */
|
|
1946
|
+
type PptxChartMarkerSymbol = 'circle' | 'dash' | 'diamond' | 'dot' | 'none' | 'picture' | 'plus' | 'square' | 'star' | 'triangle' | 'x' | 'auto';
|
|
1947
|
+
/** Shape properties extracted from c:spPr for chart formatting. */
|
|
1948
|
+
interface PptxChartShapeProps {
|
|
1949
|
+
fillColor?: string;
|
|
1950
|
+
strokeColor?: string;
|
|
1951
|
+
strokeWidth?: number;
|
|
1952
|
+
/** Line dash style (a:prstDash/@val), e.g. 'solid', 'dash', 'dot', 'lgDash'. */
|
|
1953
|
+
strokeDashStyle?: string;
|
|
1954
|
+
}
|
|
1955
|
+
/** Marker appearance on a chart series or data point. */
|
|
1956
|
+
interface PptxChartMarker {
|
|
1957
|
+
symbol: PptxChartMarkerSymbol;
|
|
1958
|
+
size?: number;
|
|
1959
|
+
spPr?: PptxChartShapeProps;
|
|
1960
|
+
}
|
|
1961
|
+
/** Per-data-point formatting override (c:dPt). */
|
|
1962
|
+
interface PptxChartDataPoint {
|
|
1963
|
+
idx: number;
|
|
1964
|
+
spPr?: PptxChartShapeProps;
|
|
1965
|
+
explosion?: number;
|
|
1966
|
+
invertIfNegative?: boolean;
|
|
1967
|
+
marker?: PptxChartMarker;
|
|
1968
|
+
}
|
|
1969
|
+
/** Individual data label override (c:dLbl). */
|
|
1970
|
+
interface PptxChartDataLabel {
|
|
1971
|
+
idx: number;
|
|
1972
|
+
showVal?: boolean;
|
|
1973
|
+
showCatName?: boolean;
|
|
1974
|
+
showSerName?: boolean;
|
|
1975
|
+
showPercent?: boolean;
|
|
1976
|
+
showLegendKey?: boolean;
|
|
1977
|
+
showBubbleSize?: boolean;
|
|
1978
|
+
position?: string;
|
|
1979
|
+
text?: string;
|
|
1980
|
+
}
|
|
1981
|
+
/** Axis number format. */
|
|
1982
|
+
interface PptxChartAxisNumFmt {
|
|
1983
|
+
formatCode: string;
|
|
1984
|
+
sourceLinked?: boolean;
|
|
1985
|
+
}
|
|
1986
|
+
/** Axis formatting for category, value, or date axes. */
|
|
1987
|
+
interface PptxChartAxisFormatting {
|
|
1988
|
+
axisType: 'catAx' | 'valAx' | 'dateAx' | 'serAx';
|
|
1989
|
+
/** Axis position: "b" (bottom), "l" (left), "r" (right), "t" (top). */
|
|
1990
|
+
axPos?: 'b' | 'l' | 'r' | 't';
|
|
1991
|
+
/** Unique axis identifier (c:axId/@val) used to link series to axes. */
|
|
1992
|
+
axisId?: number;
|
|
1993
|
+
/** Cross-axis identifier — the axis this axis crosses. */
|
|
1994
|
+
crossAxisId?: number;
|
|
1995
|
+
numFmt?: PptxChartAxisNumFmt;
|
|
1996
|
+
titleText?: string;
|
|
1997
|
+
spPr?: PptxChartShapeProps;
|
|
1998
|
+
fontFamily?: string;
|
|
1999
|
+
fontSize?: number;
|
|
2000
|
+
fontBold?: boolean;
|
|
2001
|
+
fontColor?: string;
|
|
2002
|
+
/** Whether major gridlines are present (`c:majorGridlines`). */
|
|
2003
|
+
majorGridlines?: boolean;
|
|
2004
|
+
/** Whether minor gridlines are present (`c:minorGridlines`). */
|
|
2005
|
+
minorGridlines?: boolean;
|
|
2006
|
+
majorGridlinesSpPr?: PptxChartShapeProps;
|
|
2007
|
+
minorGridlinesSpPr?: PptxChartShapeProps;
|
|
2008
|
+
/** Minimum axis value override (c:min/@val). */
|
|
2009
|
+
min?: number;
|
|
2010
|
+
/** Maximum axis value override (c:max/@val). */
|
|
2011
|
+
max?: number;
|
|
2012
|
+
/** Whether the axis is deleted/hidden (c:delete/@val). */
|
|
2013
|
+
deleted?: boolean;
|
|
2014
|
+
/**
|
|
2015
|
+
* Display units for value axis (c:dispUnits/c:builtInUnit/@val).
|
|
2016
|
+
* When set to 'custom', the actual divisor is in {@link displayUnitsValue}.
|
|
2017
|
+
*/
|
|
2018
|
+
displayUnits?: 'hundreds' | 'thousands' | 'tenThousands' | 'hundredThousands' | 'millions' | 'tenMillions' | 'hundredMillions' | 'billions' | 'trillions' | 'custom';
|
|
2019
|
+
/** Custom display unit divisor value (c:dispUnits/c:custUnit/@val). Only used when displayUnits is 'custom'. */
|
|
2020
|
+
displayUnitsValue?: number;
|
|
2021
|
+
/** Display units label text (c:dispUnits/c:dispUnitsLbl). Overrides the built-in default label when present. */
|
|
2022
|
+
displayUnitsLabel?: string;
|
|
2023
|
+
/** Whether logarithmic scaling is enabled (presence of c:scaling/c:logBase). */
|
|
2024
|
+
logScale?: boolean;
|
|
2025
|
+
/** Logarithmic base value (c:scaling/c:logBase/@val), typically 10 or e. */
|
|
2026
|
+
logBase?: number;
|
|
2027
|
+
/** Major-unit interval between primary tick marks (c:majorUnit/@val). */
|
|
2028
|
+
majorUnit?: number;
|
|
2029
|
+
/** Minor-unit interval between secondary tick marks (c:minorUnit/@val). */
|
|
2030
|
+
minorUnit?: number;
|
|
2031
|
+
/** Tick-label position (c:tickLblPos/@val): 'high', 'low', 'nextTo', or 'none'. */
|
|
2032
|
+
tickLblPos?: 'high' | 'low' | 'nextTo' | 'none';
|
|
2033
|
+
}
|
|
2034
|
+
/** 3D wall or floor element formatting. */
|
|
2035
|
+
interface PptxChart3DSurface {
|
|
2036
|
+
thickness?: number;
|
|
2037
|
+
spPr?: PptxChartShapeProps;
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* A single data series within a chart.
|
|
2041
|
+
*
|
|
2042
|
+
* @example
|
|
2043
|
+
* ```ts
|
|
2044
|
+
* const series: PptxChartSeries = {
|
|
2045
|
+
* name: "Revenue",
|
|
2046
|
+
* values: [100, 120, 140],
|
|
2047
|
+
* color: "#4F81BD",
|
|
2048
|
+
* trendlines: [{ trendlineType: "linear" }],
|
|
2049
|
+
* };
|
|
2050
|
+
* // => satisfies PptxChartSeries
|
|
2051
|
+
* ```
|
|
2052
|
+
*/
|
|
2053
|
+
interface PptxChartSeries {
|
|
2054
|
+
name: string;
|
|
2055
|
+
values: number[];
|
|
2056
|
+
color?: string;
|
|
2057
|
+
trendlines?: PptxChartTrendline[];
|
|
2058
|
+
errBars?: PptxChartErrBars[];
|
|
2059
|
+
dataPoints?: PptxChartDataPoint[];
|
|
2060
|
+
marker?: PptxChartMarker;
|
|
2061
|
+
dataLabels?: PptxChartDataLabel[];
|
|
2062
|
+
explosion?: number;
|
|
2063
|
+
/** Axis ID this series is plotted against (links to PptxChartAxisFormatting.axisId). */
|
|
2064
|
+
axisId?: number;
|
|
2065
|
+
/**
|
|
2066
|
+
* Per-series chart type, used for combo charts where individual series are
|
|
2067
|
+
* plotted with different chart types (e.g. a bar series and a line series in
|
|
2068
|
+
* the same chart). Maps to the OOXML chart-type container that holds the
|
|
2069
|
+
* series (`c:barChart`, `c:lineChart`, etc.). Omitted for single-type charts,
|
|
2070
|
+
* where the chart-level {@link PptxChartData.chartType} applies to every
|
|
2071
|
+
* series.
|
|
2072
|
+
*/
|
|
2073
|
+
seriesChartType?: PptxChartType;
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Chart-level data-label options (`c:dLbls` directly under a chart-type
|
|
2077
|
+
* container, applying to every series). Mirrors the OOXML `c:show*` flags
|
|
2078
|
+
* and `c:dLblPos`.
|
|
2079
|
+
*/
|
|
2080
|
+
interface PptxChartDataLabelOptions {
|
|
2081
|
+
/** Show the numeric value (`c:showVal`). */
|
|
2082
|
+
showValue?: boolean;
|
|
2083
|
+
/** Show the category name (`c:showCatName`). */
|
|
2084
|
+
showCategory?: boolean;
|
|
2085
|
+
/** Show the series name (`c:showSerName`). */
|
|
2086
|
+
showSeriesName?: boolean;
|
|
2087
|
+
/** Show the percentage (`c:showPercent`, pie/doughnut). */
|
|
2088
|
+
showPercent?: boolean;
|
|
2089
|
+
/** Show the legend key swatch (`c:showLegendKey`). */
|
|
2090
|
+
showLegendKey?: boolean;
|
|
2091
|
+
/**
|
|
2092
|
+
* Label position (`c:dLblPos`). Valid values depend on the chart type
|
|
2093
|
+
* (`ctr`, `inEnd`, `inBase`, `outEnd`, `bestFit`, `l`, `r`, `t`, `b`).
|
|
2094
|
+
* Omit to let PowerPoint use the type default.
|
|
2095
|
+
*/
|
|
2096
|
+
position?: 'ctr' | 'inEnd' | 'inBase' | 'outEnd' | 'bestFit' | 'l' | 'r' | 't' | 'b';
|
|
2097
|
+
}
|
|
2098
|
+
/**
|
|
2099
|
+
* Style / formatting metadata for a chart.
|
|
2100
|
+
*
|
|
2101
|
+
* @example
|
|
2102
|
+
* ```ts
|
|
2103
|
+
* const style: PptxChartStyle = {
|
|
2104
|
+
* styleId: 2,
|
|
2105
|
+
* hasLegend: true,
|
|
2106
|
+
* legendPosition: "b",
|
|
2107
|
+
* hasDataLabels: true,
|
|
2108
|
+
* };
|
|
2109
|
+
* // => satisfies PptxChartStyle
|
|
2110
|
+
* ```
|
|
2111
|
+
*/
|
|
2112
|
+
interface PptxChartStyle {
|
|
2113
|
+
/** Chart style index from `c:style/@val`. */
|
|
2114
|
+
styleId?: number;
|
|
2115
|
+
/** Whether the chart has a visible legend. */
|
|
2116
|
+
hasLegend?: boolean;
|
|
2117
|
+
/** Legend position (t, b, l, r, tr). */
|
|
2118
|
+
legendPosition?: string;
|
|
2119
|
+
/** Whether the chart has a title. */
|
|
2120
|
+
hasTitle?: boolean;
|
|
2121
|
+
/** Whether gridlines are visible. */
|
|
2122
|
+
hasGridlines?: boolean;
|
|
2123
|
+
/** Whether data labels are shown. */
|
|
2124
|
+
hasDataLabels?: boolean;
|
|
2125
|
+
/** Chart-level data-label content/position options (when `hasDataLabels`). */
|
|
2126
|
+
dataLabels?: PptxChartDataLabelOptions;
|
|
2127
|
+
}
|
|
2128
|
+
/**
|
|
2129
|
+
* External data source reference for a chart (c:externalData).
|
|
2130
|
+
*
|
|
2131
|
+
* Charts can reference an external Excel workbook via a relationship ID
|
|
2132
|
+
* that points to an external file (TargetMode="External"). The
|
|
2133
|
+
* `autoUpdate` flag indicates whether the chart should refresh its
|
|
2134
|
+
* cached data from the external source on open.
|
|
2135
|
+
*
|
|
2136
|
+
* @example
|
|
2137
|
+
* ```ts
|
|
2138
|
+
* const ext: PptxExternalData = {
|
|
2139
|
+
* relId: "rId2",
|
|
2140
|
+
* targetPath: "file:///C:/Data/budget.xlsx",
|
|
2141
|
+
* autoUpdate: true,
|
|
2142
|
+
* };
|
|
2143
|
+
* // => satisfies PptxExternalData
|
|
2144
|
+
* ```
|
|
2145
|
+
*/
|
|
2146
|
+
interface PptxExternalData {
|
|
2147
|
+
/** Relationship ID referencing the external data source in the chart .rels. */
|
|
2148
|
+
relId: string;
|
|
2149
|
+
/** Resolved external file path or URL from the relationship target. */
|
|
2150
|
+
targetPath?: string;
|
|
2151
|
+
/** Whether to auto-update data from the external source on open. */
|
|
2152
|
+
autoUpdate?: boolean;
|
|
2153
|
+
/** Raw binary data of the embedded xlsx workbook (from ppt/embeddings/). */
|
|
2154
|
+
embeddedWorkbookData?: Uint8Array;
|
|
2155
|
+
}
|
|
2156
|
+
/**
|
|
2157
|
+
* Options specific to the OOXML "Pie of Pie" / "Bar of Pie" chart
|
|
2158
|
+
* (`c:ofPieChart`, ECMA-376 §21.2.2.126 / CT_OfPieChart).
|
|
2159
|
+
*
|
|
2160
|
+
* The primary discriminator is {@link ofPieType}: `"pie"` produces a
|
|
2161
|
+
* pie-of-pie chart whose secondary plot is itself a pie, while `"bar"`
|
|
2162
|
+
* produces a bar-of-pie chart whose secondary plot is a horizontal bar.
|
|
2163
|
+
*
|
|
2164
|
+
* - {@link splitType} chooses the split rule.
|
|
2165
|
+
* - {@link splitPos} is the threshold value used by `pos`/`val`/`percent`.
|
|
2166
|
+
* - {@link secondPieSize} controls the secondary plot's size (5–200%).
|
|
2167
|
+
* - {@link serLines} toggles the leader lines connecting the plots.
|
|
2168
|
+
* - {@link gapWidth} is the gap between the plots in percent (0–500).
|
|
2169
|
+
*/
|
|
2170
|
+
interface PptxChartOfPieOptions {
|
|
2171
|
+
ofPieType: 'pie' | 'bar';
|
|
2172
|
+
splitType?: 'auto' | 'cust' | 'percent' | 'pos' | 'val';
|
|
2173
|
+
splitPos?: number;
|
|
2174
|
+
custSplit?: number[];
|
|
2175
|
+
secondPieSize?: number;
|
|
2176
|
+
serLines?: boolean;
|
|
2177
|
+
gapWidth?: number;
|
|
2178
|
+
}
|
|
2179
|
+
/**
|
|
2180
|
+
* 3D viewing parameters for a chart (`c:view3D`, ECMA-376 §21.2.2.228 /
|
|
2181
|
+
* CT_View3D).
|
|
2182
|
+
*
|
|
2183
|
+
* All fields are optional and round-trip verbatim.
|
|
2184
|
+
*
|
|
2185
|
+
* - {@link rotX} — X-axis rotation in degrees (-90…90).
|
|
2186
|
+
* - {@link rotY} — Y-axis rotation in degrees (0…360).
|
|
2187
|
+
* - {@link depthPercent} — chart depth as a percentage of base width.
|
|
2188
|
+
* - {@link rAngAx} — `true` if axes meet at right angles.
|
|
2189
|
+
* - {@link perspective} — perspective angle in degrees (0…240).
|
|
2190
|
+
* - {@link hPercent} — height as a percentage of chart width.
|
|
2191
|
+
*/
|
|
2192
|
+
interface PptxChartView3D {
|
|
2193
|
+
rotX?: number;
|
|
2194
|
+
rotY?: number;
|
|
2195
|
+
depthPercent?: number;
|
|
2196
|
+
rAngAx?: boolean;
|
|
2197
|
+
perspective?: number;
|
|
2198
|
+
hPercent?: number;
|
|
2199
|
+
}
|
|
2200
|
+
/**
|
|
2201
|
+
* Chart "chrome" flags from `c:chart` that round-trip cleanly even when
|
|
2202
|
+
* rendering ignores them.
|
|
2203
|
+
*
|
|
2204
|
+
* - {@link autoTitleDeleted} — `c:autoTitleDeleted/@val`. Suppresses the
|
|
2205
|
+
* auto-generated title for single-series charts.
|
|
2206
|
+
* - {@link dispBlanksAs} — `c:dispBlanksAs/@val`. How blank cells
|
|
2207
|
+
* render: `"gap"`, `"zero"`, or `"span"`.
|
|
2208
|
+
* - {@link showDLblsOverMax} — `c:showDLblsOverMax/@val`. Keeps data
|
|
2209
|
+
* labels visible for points exceeding the value-axis maximum.
|
|
2210
|
+
*
|
|
2211
|
+
* `c:plotVisOnly` lives on {@link PptxChartData.plotVisibleOnly} and is
|
|
2212
|
+
* intentionally not duplicated here.
|
|
2213
|
+
*/
|
|
2214
|
+
interface PptxChartChrome {
|
|
2215
|
+
autoTitleDeleted?: boolean;
|
|
2216
|
+
dispBlanksAs?: 'gap' | 'zero' | 'span';
|
|
2217
|
+
showDLblsOverMax?: boolean;
|
|
2218
|
+
}
|
|
2219
|
+
/** Parsed data extracted from an embedded xlsx workbook. */
|
|
2220
|
+
interface PptxEmbeddedWorkbookData {
|
|
2221
|
+
/** Category labels from the first column/row. */
|
|
2222
|
+
categories: string[];
|
|
2223
|
+
/** Data series extracted from worksheet cells. */
|
|
2224
|
+
series: Array<{
|
|
2225
|
+
name: string;
|
|
2226
|
+
values: number[];
|
|
2227
|
+
}>;
|
|
2228
|
+
}
|
|
2229
|
+
/**
|
|
2230
|
+
* Complete parsed chart data for a {@link ChartPptxElement}.
|
|
2231
|
+
*
|
|
2232
|
+
* @example
|
|
2233
|
+
* ```ts
|
|
2234
|
+
* const chart: PptxChartData = {
|
|
2235
|
+
* title: "Q4 Sales",
|
|
2236
|
+
* chartType: "bar",
|
|
2237
|
+
* categories: ["Jan", "Feb", "Mar"],
|
|
2238
|
+
* series: [
|
|
2239
|
+
* { name: "Revenue", values: [100, 120, 140] },
|
|
2240
|
+
* ],
|
|
2241
|
+
* grouping: "clustered",
|
|
2242
|
+
* style: { hasLegend: true, legendPosition: "b" },
|
|
2243
|
+
* };
|
|
2244
|
+
* // => satisfies PptxChartData
|
|
2245
|
+
* ```
|
|
2246
|
+
*/
|
|
2247
|
+
interface PptxChartData {
|
|
2248
|
+
title?: string;
|
|
2249
|
+
chartType: PptxChartType;
|
|
2250
|
+
categories: string[];
|
|
2251
|
+
series: PptxChartSeries[];
|
|
2252
|
+
/** Chart style/formatting metadata. */
|
|
2253
|
+
style?: PptxChartStyle;
|
|
2254
|
+
/** Grouping mode for bar/area/line charts: 'clustered' | 'stacked' | 'percentStacked' */
|
|
2255
|
+
grouping?: 'clustered' | 'stacked' | 'percentStacked';
|
|
2256
|
+
/** Internal: path to the chart XML part in the PPTX archive (for round-trip save). */
|
|
2257
|
+
chartPartPath?: string;
|
|
2258
|
+
/** Internal: relationship ID linking the graphic frame to the chart part. */
|
|
2259
|
+
chartRelationshipId?: string;
|
|
2260
|
+
dataTable?: PptxChartDataTable;
|
|
2261
|
+
dropLines?: PptxChartLineStyle;
|
|
2262
|
+
hiLowLines?: PptxChartLineStyle;
|
|
2263
|
+
axes?: PptxChartAxisFormatting[];
|
|
2264
|
+
floor?: PptxChart3DSurface;
|
|
2265
|
+
sideWall?: PptxChart3DSurface;
|
|
2266
|
+
backWall?: PptxChart3DSurface;
|
|
2267
|
+
/** External data source reference (c:externalData) linking to an external workbook. */
|
|
2268
|
+
externalData?: PptxExternalData;
|
|
2269
|
+
/**
|
|
2270
|
+
* Parsed data from the embedded xlsx workbook (from ppt/embeddings/).
|
|
2271
|
+
*
|
|
2272
|
+
* When a chart references an embedded Excel workbook via `c:externalData`,
|
|
2273
|
+
* the xlsx is parsed to extract categories and series. This data serves as
|
|
2274
|
+
* a fallback when the chart XML's cached series data is empty or incomplete.
|
|
2275
|
+
*/
|
|
2276
|
+
embeddedWorkbookData?: PptxEmbeddedWorkbookData;
|
|
2277
|
+
/**
|
|
2278
|
+
* Pivot table data source reference (c:pivotSource).
|
|
2279
|
+
*
|
|
2280
|
+
* When present, the chart's data originates from a PivotTable.
|
|
2281
|
+
* The chart still renders using its cached series data; this field
|
|
2282
|
+
* is metadata about the data origin, preserved for round-trip fidelity.
|
|
2283
|
+
*/
|
|
2284
|
+
pivotSource?: {
|
|
2285
|
+
/** Pivot table reference name, e.g. "[workbook.xlsx]Sheet1!PivotTable1". */
|
|
2286
|
+
name: string;
|
|
2287
|
+
/** Format identifier from c:fmtId/@val. */
|
|
2288
|
+
formatId?: number;
|
|
2289
|
+
};
|
|
2290
|
+
/**
|
|
2291
|
+
* Whether only visible cells are plotted (c:plotVisOnly).
|
|
2292
|
+
* When `true` (the default), hidden cells are excluded from the chart.
|
|
2293
|
+
* When `false`, hidden data IS plotted.
|
|
2294
|
+
*/
|
|
2295
|
+
plotVisibleOnly?: boolean;
|
|
2296
|
+
/**
|
|
2297
|
+
* Color palette extracted from the chart's Office 2013+ color style part
|
|
2298
|
+
* (`chartColorStyle*.xml`). When present, this palette takes priority over
|
|
2299
|
+
* the `c:style/@val`-derived palette in `getChartStylePalette`.
|
|
2300
|
+
*
|
|
2301
|
+
* Each entry is a resolved hex colour string (e.g. `"#4472C4"`).
|
|
2302
|
+
*/
|
|
2303
|
+
colorPalette?: string[];
|
|
2304
|
+
/**
|
|
2305
|
+
* Color cycling method from the chart color style part's `meth` attribute.
|
|
2306
|
+
*
|
|
2307
|
+
* - `"cycle"` — repeat the palette colours in order (default)
|
|
2308
|
+
* - `"withinLinear"` — gradient within each series
|
|
2309
|
+
* - `"acrossLinear"` — gradient across series
|
|
2310
|
+
*/
|
|
2311
|
+
colorMethod?: 'cycle' | 'withinLinear' | 'acrossLinear';
|
|
2312
|
+
/**
|
|
2313
|
+
* Pie-of-pie / Bar-of-pie options (`c:ofPieChart`, CT_OfPieChart).
|
|
2314
|
+
*
|
|
2315
|
+
* Present only when {@link chartType} is `"ofPie"`. Carries the split
|
|
2316
|
+
* configuration, secondary plot size, and serLines flag so that an
|
|
2317
|
+
* `ofPieChart` element can be re-emitted on save with full fidelity.
|
|
2318
|
+
*/
|
|
2319
|
+
ofPieOptions?: PptxChartOfPieOptions;
|
|
2320
|
+
/**
|
|
2321
|
+
* 3D viewing parameters (`c:view3D`, CT_View3D).
|
|
2322
|
+
*
|
|
2323
|
+
* Parsed from and emitted to `c:chart/c:view3D`. Absent when the
|
|
2324
|
+
* chart XML has no `c:view3D` element.
|
|
2325
|
+
*/
|
|
2326
|
+
view3D?: PptxChartView3D;
|
|
2327
|
+
/**
|
|
2328
|
+
* Top-level chart chrome flags (`c:autoTitleDeleted`,
|
|
2329
|
+
* `c:dispBlanksAs`, `c:showDLblsOverMax`).
|
|
2330
|
+
*
|
|
2331
|
+
* Each flag is omitted from the emitted XML when absent on the
|
|
2332
|
+
* source data, so absence does not produce empty `<c:…/>` placeholders.
|
|
2333
|
+
*/
|
|
2334
|
+
chartChrome?: PptxChartChrome;
|
|
2335
|
+
/**
|
|
2336
|
+
* Raw `c:userShapes` XML subtree (a drawing tree) preserved verbatim.
|
|
2337
|
+
*
|
|
2338
|
+
* `c:userShapes` references a separate drawing part containing
|
|
2339
|
+
* shapes drawn over the chart. The reference is preserved as-is so
|
|
2340
|
+
* that round-trip save re-emits the original element without
|
|
2341
|
+
* attempting to parse the nested drawing tree.
|
|
2342
|
+
*/
|
|
2343
|
+
userShapesXml?: unknown;
|
|
2344
|
+
/**
|
|
2345
|
+
* Raw `c:pivotFmts` XML subtree preserved verbatim.
|
|
2346
|
+
*
|
|
2347
|
+
* `c:pivotFmts` carries a list of `c:pivotFmt` formatting overrides
|
|
2348
|
+
* for charts whose data originates from a PivotTable. Preserved
|
|
2349
|
+
* verbatim for round-trip fidelity.
|
|
2350
|
+
*/
|
|
2351
|
+
pivotFmtsXml?: unknown;
|
|
2352
|
+
/**
|
|
2353
|
+
* Color-map override (`c:clrMapOvr`) carrying 12 attributes that
|
|
2354
|
+
* remap theme colour roles for this chart only. Preserved as a flat
|
|
2355
|
+
* `attribute → value` map for round-trip fidelity.
|
|
2356
|
+
*/
|
|
2357
|
+
clrMapOvr?: Record<string, string>;
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
/**
|
|
2361
|
+
* Image types: effects, crop shapes, and properties shared by image/picture
|
|
2362
|
+
* elements.
|
|
2363
|
+
*
|
|
2364
|
+
* @module pptx-types/image
|
|
2365
|
+
*/
|
|
2366
|
+
/**
|
|
2367
|
+
* Blend mode for `a:blend` container nodes inside an `a:effectDag` (CT_BlendEffect).
|
|
2368
|
+
*
|
|
2369
|
+
* Per ECMA-376 §20.1.8.10, valid values are: `darken`, `lighten`, `mult`,
|
|
2370
|
+
* `over`, `screen`.
|
|
2371
|
+
*/
|
|
2372
|
+
type EffectDagBlendMode = 'darken' | 'lighten' | 'mult' | 'over' | 'screen';
|
|
2373
|
+
/**
|
|
2374
|
+
* Container node kind inside an `a:effectDag` (CT_EffectContainer @type).
|
|
2375
|
+
*
|
|
2376
|
+
* Per ECMA-376 §20.1.8.20, `sib` (sibling) draws each child independently
|
|
2377
|
+
* over the same source; `tree` (tree) chains effects so each sees the output
|
|
2378
|
+
* of its siblings.
|
|
2379
|
+
*/
|
|
2380
|
+
type EffectDagContainerType = 'sib' | 'tree';
|
|
2381
|
+
/**
|
|
2382
|
+
* Typed model of the directed-acyclic effect graph stored in `a:effectDag`.
|
|
2383
|
+
*
|
|
2384
|
+
* The four "structural" container/transform nodes are typed; any other inner
|
|
2385
|
+
* effect (e.g. `a:outerShdw`, `a:glow`, `a:alphaInv`) is preserved verbatim
|
|
2386
|
+
* as a raw XML object via the {@link EffectDagRawLeaf} variant so we never
|
|
2387
|
+
* have to recurse into the full effect taxonomy.
|
|
2388
|
+
*
|
|
2389
|
+
* @example
|
|
2390
|
+
* ```ts
|
|
2391
|
+
* // <a:effectDag>
|
|
2392
|
+
* // <a:cont type="sib">
|
|
2393
|
+
* // <a:blend blend="mult"><a:cont type="tree" /></a:blend>
|
|
2394
|
+
* // </a:cont>
|
|
2395
|
+
* // </a:effectDag>
|
|
2396
|
+
* const dag: EffectDagContainer = {
|
|
2397
|
+
* kind: "cont",
|
|
2398
|
+
* type: "sib",
|
|
2399
|
+
* children: [{
|
|
2400
|
+
* kind: "blend",
|
|
2401
|
+
* mode: "mult",
|
|
2402
|
+
* container: { kind: "cont", type: "tree", children: [] },
|
|
2403
|
+
* }],
|
|
2404
|
+
* };
|
|
2405
|
+
* ```
|
|
2406
|
+
*/
|
|
2407
|
+
type EffectDagNode = EffectDagContainer | EffectDagBlend | EffectDagXfrm | EffectDagRelOff | EffectDagRawLeaf;
|
|
2408
|
+
/** `a:cont` — CT_EffectContainer. Recursive; mirrors the top-level `effectDag`. */
|
|
2409
|
+
interface EffectDagContainer {
|
|
2410
|
+
kind: 'cont';
|
|
2411
|
+
/** `@type` — `sib` or `tree`. */
|
|
2412
|
+
type: EffectDagContainerType;
|
|
2413
|
+
/** Optional `@name` attribute. */
|
|
2414
|
+
name?: string;
|
|
2415
|
+
/** Ordered children. */
|
|
2416
|
+
children: EffectDagNode[];
|
|
2417
|
+
}
|
|
2418
|
+
/** `a:blend` — CT_BlendEffect. Always wraps a single `a:cont` child. */
|
|
2419
|
+
interface EffectDagBlend {
|
|
2420
|
+
kind: 'blend';
|
|
2421
|
+
/** `@blend` attribute. */
|
|
2422
|
+
mode: EffectDagBlendMode;
|
|
2423
|
+
/** Required child `a:cont` container. */
|
|
2424
|
+
container: EffectDagContainer;
|
|
2425
|
+
}
|
|
2426
|
+
/** `a:xfrmEffect` — CT_TransformEffect. Affine transform with no children. */
|
|
2427
|
+
interface EffectDagXfrm {
|
|
2428
|
+
kind: 'xfrmEffect';
|
|
2429
|
+
/** Horizontal scale, percentage * 1000 (e.g. 100000 = 100%). */
|
|
2430
|
+
sx?: number;
|
|
2431
|
+
/** Vertical scale, percentage * 1000. */
|
|
2432
|
+
sy?: number;
|
|
2433
|
+
/** Horizontal skew, degrees * 60000. */
|
|
2434
|
+
kx?: number;
|
|
2435
|
+
/** Vertical skew, degrees * 60000. */
|
|
2436
|
+
ky?: number;
|
|
2437
|
+
/** Horizontal translation in EMU. */
|
|
2438
|
+
tx?: number;
|
|
2439
|
+
/** Vertical translation in EMU. */
|
|
2440
|
+
ty?: number;
|
|
2441
|
+
}
|
|
2442
|
+
/** `a:relOff` — CT_RelativeOffsetEffect. Relative offset in 1000ths of a percent. */
|
|
2443
|
+
interface EffectDagRelOff {
|
|
2444
|
+
kind: 'relOff';
|
|
2445
|
+
/** Horizontal offset, percentage * 1000. */
|
|
2446
|
+
tx?: number;
|
|
2447
|
+
/** Vertical offset, percentage * 1000. */
|
|
2448
|
+
ty?: number;
|
|
2449
|
+
}
|
|
2450
|
+
/**
|
|
2451
|
+
* Catch-all leaf preserving any non-container effect (e.g. `a:outerShdw`,
|
|
2452
|
+
* `a:glow`, `a:alphaInv`) as raw XML. Re-emitted verbatim on save.
|
|
2453
|
+
*/
|
|
2454
|
+
interface EffectDagRawLeaf {
|
|
2455
|
+
kind: 'raw';
|
|
2456
|
+
/** Local element name without the `a:` prefix (e.g. `outerShdw`, `glow`). */
|
|
2457
|
+
tag: string;
|
|
2458
|
+
/** Raw XML object captured at load — preserved verbatim on save. */
|
|
2459
|
+
xml: Record<string, unknown>;
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* Image recolour/adjustment properties parsed from blip extensions.
|
|
2463
|
+
*
|
|
2464
|
+
* These effects are stored in the OpenXML `<a:blip>` extension list
|
|
2465
|
+
* and applied non-destructively to the original image data.
|
|
2466
|
+
*
|
|
2467
|
+
* @example
|
|
2468
|
+
* ```ts
|
|
2469
|
+
* const fx: PptxImageEffects = {
|
|
2470
|
+
* brightness: 20,
|
|
2471
|
+
* contrast: -10,
|
|
2472
|
+
* grayscale: true,
|
|
2473
|
+
* };
|
|
2474
|
+
* // => { brightness: 20, contrast: -10, grayscale: true } satisfies PptxImageEffects
|
|
2475
|
+
* ```
|
|
2476
|
+
*/
|
|
2477
|
+
interface PptxImageEffects {
|
|
2478
|
+
/** Brightness adjustment (-100 to 100). */
|
|
2479
|
+
brightness?: number;
|
|
2480
|
+
/** Contrast adjustment (-100 to 100). */
|
|
2481
|
+
contrast?: number;
|
|
2482
|
+
/** Duotone colour pair. */
|
|
2483
|
+
duotone?: {
|
|
2484
|
+
color1: string;
|
|
2485
|
+
color2: string;
|
|
2486
|
+
};
|
|
2487
|
+
/** Grayscale flag. */
|
|
2488
|
+
grayscale?: boolean;
|
|
2489
|
+
/** Saturation adjustment (-100 to 100). */
|
|
2490
|
+
saturation?: number;
|
|
2491
|
+
/** Color wash overlay. */
|
|
2492
|
+
colorWash?: {
|
|
2493
|
+
color: string;
|
|
2494
|
+
opacity: number;
|
|
2495
|
+
};
|
|
2496
|
+
/** Artistic effect name (blur, pencilGrayscale, paintStrokes, etc.). */
|
|
2497
|
+
artisticEffect?: string;
|
|
2498
|
+
/** Artistic effect radius/amount. */
|
|
2499
|
+
artisticRadius?: number;
|
|
2500
|
+
/** Alpha modulation fixed — overall opacity (0-100, where 100 = fully opaque). */
|
|
2501
|
+
alphaModFix?: number;
|
|
2502
|
+
/** Bi-level threshold — converts to 1-bit black/white (0-100). */
|
|
2503
|
+
biLevel?: number;
|
|
2504
|
+
/** Colour change — swap one colour range for another (used for transparency keying). */
|
|
2505
|
+
clrChange?: {
|
|
2506
|
+
clrFrom: string;
|
|
2507
|
+
clrTo: string;
|
|
2508
|
+
/** Whether the target colour is fully transparent (alpha = 0). */
|
|
2509
|
+
clrToTransparent?: boolean;
|
|
2510
|
+
};
|
|
2511
|
+
/**
|
|
2512
|
+
* Alpha inverse effect (`a:alphaInv`). Inverts the alpha channel; an optional
|
|
2513
|
+
* colour child shifts the inversion baseline.
|
|
2514
|
+
*/
|
|
2515
|
+
alphaInv?: {
|
|
2516
|
+
/** Optional baseline colour (hex). */
|
|
2517
|
+
color?: string;
|
|
2518
|
+
};
|
|
2519
|
+
/** Alpha ceiling (`a:alphaCeiling`) — clamps any non-zero alpha to fully opaque. Boolean flag. */
|
|
2520
|
+
alphaCeiling?: boolean;
|
|
2521
|
+
/** Alpha floor (`a:alphaFloor`) — clamps any non-fully-opaque alpha to fully transparent. Boolean flag. */
|
|
2522
|
+
alphaFloor?: boolean;
|
|
2523
|
+
/**
|
|
2524
|
+
* Alpha modulate (`a:alphaMod`). The schema requires a single `cont` (effect
|
|
2525
|
+
* container) child; we preserve the inner XML opaquely for round-trip.
|
|
2526
|
+
*/
|
|
2527
|
+
alphaMod?: {
|
|
2528
|
+
/** Raw opaque XML for the `a:cont` child to preserve on save. */
|
|
2529
|
+
contRawXml?: Record<string, unknown>;
|
|
2530
|
+
};
|
|
2531
|
+
/** Alpha replace (`a:alphaRepl`) — replaces alpha with the given fixed-percent value (0..100). */
|
|
2532
|
+
alphaRepl?: number;
|
|
2533
|
+
/** Alpha bi-level (`a:alphaBiLevel`) — threshold (0..100) above which alpha becomes fully opaque. */
|
|
2534
|
+
alphaBiLevel?: number;
|
|
2535
|
+
/**
|
|
2536
|
+
* Colour replace (`a:clrRepl`) — replaces all colour information in an image
|
|
2537
|
+
* with the given solid colour. Stores the raw colour child to preserve scheme
|
|
2538
|
+
* colour references and modifiers.
|
|
2539
|
+
*/
|
|
2540
|
+
clrRepl?: {
|
|
2541
|
+
/** Resolved hex colour. */
|
|
2542
|
+
color: string;
|
|
2543
|
+
/** Raw opaque colour XML for round-trip. */
|
|
2544
|
+
rawXml?: Record<string, unknown>;
|
|
2545
|
+
};
|
|
2546
|
+
/** Luminance modulation (`a:lum`) — bright/contrast as fixed percentages (0..100). */
|
|
2547
|
+
lum?: {
|
|
2548
|
+
bright?: number;
|
|
2549
|
+
contrast?: number;
|
|
2550
|
+
};
|
|
2551
|
+
/** HSL modulation (`a:hsl`) — hue (0..360 degrees), saturation/luminance (-100..100). */
|
|
2552
|
+
hsl?: {
|
|
2553
|
+
hue?: number;
|
|
2554
|
+
sat?: number;
|
|
2555
|
+
lum?: number;
|
|
2556
|
+
};
|
|
2557
|
+
/** Image-effect tint (`a:tint` inside blip) — hue (0..360), amount (-100..100). */
|
|
2558
|
+
tint?: {
|
|
2559
|
+
hue?: number;
|
|
2560
|
+
amt?: number;
|
|
2561
|
+
};
|
|
2562
|
+
/**
|
|
2563
|
+
* Fill overlay (`a:fillOverlay`) — overlays a fill on top of the blip.
|
|
2564
|
+
* Stores blend mode and the raw inner fill XML for round-trip.
|
|
2565
|
+
*/
|
|
2566
|
+
fillOverlay?: {
|
|
2567
|
+
blend: 'over' | 'mult' | 'screen' | 'darken' | 'lighten';
|
|
2568
|
+
/** Raw opaque fill XML preserved for round-trip. */
|
|
2569
|
+
fillRawXml?: Record<string, unknown>;
|
|
2570
|
+
};
|
|
2571
|
+
/** Blur (`a:blur`) — radius in EMU and grow flag. */
|
|
2572
|
+
blur?: {
|
|
2573
|
+
rad?: number;
|
|
2574
|
+
grow?: boolean;
|
|
2575
|
+
};
|
|
2576
|
+
}
|
|
2577
|
+
/**
|
|
2578
|
+
* Shape names used for crop-to-shape (CSS `clip-path` equivalent).
|
|
2579
|
+
*
|
|
2580
|
+
* @example
|
|
2581
|
+
* ```ts
|
|
2582
|
+
* const shape: PptxCropShape = "ellipse";
|
|
2583
|
+
* // => "ellipse" — one of: none | ellipse | roundedRect | triangle | diamond | pentagon | hexagon | star
|
|
2584
|
+
* ```
|
|
2585
|
+
*/
|
|
2586
|
+
type PptxCropShape = 'none' | 'ellipse' | 'roundedRect' | 'triangle' | 'diamond' | 'pentagon' | 'hexagon' | 'star';
|
|
2587
|
+
/**
|
|
2588
|
+
* Image content mixin — present on image and picture elements.
|
|
2589
|
+
*
|
|
2590
|
+
* Contains the decoded image data (base64 data URL or archive path),
|
|
2591
|
+
* alt text, crop insets, tiling settings, and image effects.
|
|
2592
|
+
*
|
|
2593
|
+
* @example
|
|
2594
|
+
* ```ts
|
|
2595
|
+
* const props: PptxImageProperties = {
|
|
2596
|
+
* imagePath: "ppt/media/image1.png",
|
|
2597
|
+
* altText: "Company logo",
|
|
2598
|
+
* cropLeft: 0.05,
|
|
2599
|
+
* cropRight: 0.05,
|
|
2600
|
+
* };
|
|
2601
|
+
* // => { imagePath: "ppt/media/image1.png", altText: "Company logo", cropLeft: 0.05, cropRight: 0.05 }
|
|
2602
|
+
* ```
|
|
2603
|
+
*/
|
|
2604
|
+
interface PptxImageProperties {
|
|
2605
|
+
/** Base64 data-URL for the decoded image. */
|
|
2606
|
+
imageData?: string;
|
|
2607
|
+
/** Path within the PPTX ZIP archive. */
|
|
2608
|
+
imagePath?: string;
|
|
2609
|
+
/** Base64 data-URL for an SVG variant (from blip extension asvg:svgBlip). Preferred over raster when available. */
|
|
2610
|
+
svgData?: string;
|
|
2611
|
+
/** Path to the SVG file within the PPTX ZIP archive. */
|
|
2612
|
+
svgPath?: string;
|
|
2613
|
+
/** Alt text / description from `p:cNvPr/@descr`. */
|
|
2614
|
+
altText?: string;
|
|
2615
|
+
/** Crop from left edge as 0..1 fraction (OOXML `a:srcRect/@l`). */
|
|
2616
|
+
cropLeft?: number;
|
|
2617
|
+
/** Crop from top edge as 0..1 fraction (OOXML `a:srcRect/@t`). */
|
|
2618
|
+
cropTop?: number;
|
|
2619
|
+
/** Crop from right edge as 0..1 fraction (OOXML `a:srcRect/@r`). */
|
|
2620
|
+
cropRight?: number;
|
|
2621
|
+
/** Crop from bottom edge as 0..1 fraction (OOXML `a:srcRect/@b`). */
|
|
2622
|
+
cropBottom?: number;
|
|
2623
|
+
/** Image tiling offset X in px. */
|
|
2624
|
+
tileOffsetX?: number;
|
|
2625
|
+
/** Image tiling offset Y in px. */
|
|
2626
|
+
tileOffsetY?: number;
|
|
2627
|
+
/** Image tiling scale X as percentage (100 = 100%). */
|
|
2628
|
+
tileScaleX?: number;
|
|
2629
|
+
/** Image tiling scale Y as percentage (100 = 100%). */
|
|
2630
|
+
tileScaleY?: number;
|
|
2631
|
+
/** Image tiling flip mode. */
|
|
2632
|
+
tileFlip?: 'none' | 'x' | 'y' | 'xy';
|
|
2633
|
+
/** Image tiling alignment. */
|
|
2634
|
+
tileAlignment?: string;
|
|
2635
|
+
/** Image recolour/artistic effect properties. */
|
|
2636
|
+
imageEffects?: PptxImageEffects;
|
|
2637
|
+
/** Crop-to-shape — CSS clip-path shape name. */
|
|
2638
|
+
cropShape?: PptxCropShape;
|
|
2639
|
+
}
|
|
2640
|
+
declare module "./index" {
|
|
2641
|
+
interface TextStyle {
|
|
2642
|
+
/**
|
|
2643
|
+
* Raw `a:effectDag` XML node from `a:rPr`, preserved verbatim for
|
|
2644
|
+
* round-trip serialisation. Mirrors the shape-level
|
|
2645
|
+
* {@link import('./shape-style').ShapeStyle.effectDagXml} field.
|
|
2646
|
+
*/
|
|
2647
|
+
textEffectDagXml?: XmlObject;
|
|
2648
|
+
/**
|
|
2649
|
+
* Typed effect graph parsed from `textEffectDagXml`. The four structural
|
|
2650
|
+
* container nodes (`a:cont`, `a:blend`, `a:xfrmEffect`, `a:relOff`) are
|
|
2651
|
+
* fully typed; any other leaf effect is captured as
|
|
2652
|
+
* {@link EffectDagRawLeaf} so we never have to recurse into the full
|
|
2653
|
+
* effect taxonomy.
|
|
2654
|
+
*/
|
|
2655
|
+
textEffectDagTree?: EffectDagContainer;
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
declare module "./index" {
|
|
2659
|
+
interface ShapeStyle {
|
|
2660
|
+
/**
|
|
2661
|
+
* Typed effect graph parsed from {@link ShapeStyle.effectDagXml}. The four
|
|
2662
|
+
* structural container nodes (`a:cont`, `a:blend`, `a:xfrmEffect`,
|
|
2663
|
+
* `a:relOff`) are fully typed; any other leaf effect (e.g. `a:outerShdw`,
|
|
2664
|
+
* `a:glow`, `a:alphaInv`) is captured as {@link EffectDagRawLeaf} so we
|
|
2665
|
+
* never have to recurse into the full effect taxonomy.
|
|
2666
|
+
*/
|
|
2667
|
+
effectDagTree?: EffectDagContainer;
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
/**
|
|
2672
|
+
* Media types: audio/video discriminator, bookmarks, runtime metadata,
|
|
2673
|
+
* and caption/subtitle tracks.
|
|
2674
|
+
*
|
|
2675
|
+
* @module pptx-types/media
|
|
2676
|
+
*/
|
|
2677
|
+
/**
|
|
2678
|
+
* Discriminator for embedded media element types.
|
|
2679
|
+
*
|
|
2680
|
+
* @example
|
|
2681
|
+
* ```ts
|
|
2682
|
+
* const kind: PptxMediaType = "video";
|
|
2683
|
+
* // => "video" — one of: "video" | "audio" | "unknown"
|
|
2684
|
+
* ```
|
|
2685
|
+
*/
|
|
2686
|
+
type PptxMediaType = 'video' | 'audio' | 'unknown';
|
|
2687
|
+
/**
|
|
2688
|
+
* A named bookmark within a media clip timeline.
|
|
2689
|
+
*
|
|
2690
|
+
* @example
|
|
2691
|
+
* ```ts
|
|
2692
|
+
* const bm: MediaBookmark = {
|
|
2693
|
+
* id: "bm1",
|
|
2694
|
+
* time: 12.5,
|
|
2695
|
+
* label: "Intro ends",
|
|
2696
|
+
* };
|
|
2697
|
+
* // => satisfies MediaBookmark
|
|
2698
|
+
* ```
|
|
2699
|
+
*/
|
|
2700
|
+
interface MediaBookmark {
|
|
2701
|
+
id: string;
|
|
2702
|
+
/** Position in seconds from the start of the clip. */
|
|
2703
|
+
time: number;
|
|
2704
|
+
/** User-visible label for this bookmark. */
|
|
2705
|
+
label: string;
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Runtime-extracted metadata about a media clip (populated from HTMLMediaElement).
|
|
2709
|
+
*
|
|
2710
|
+
* @example
|
|
2711
|
+
* ```ts
|
|
2712
|
+
* const meta: MediaMetadata = {
|
|
2713
|
+
* duration: 120.5,
|
|
2714
|
+
* videoWidth: 1920,
|
|
2715
|
+
* videoHeight: 1080,
|
|
2716
|
+
* codecInfo: "video/mp4; codecs=\"avc1.640028\"",
|
|
2717
|
+
* };
|
|
2718
|
+
* // => satisfies MediaMetadata
|
|
2719
|
+
* ```
|
|
2720
|
+
*/
|
|
2721
|
+
interface MediaMetadata {
|
|
2722
|
+
/** Duration in seconds. */
|
|
2723
|
+
duration?: number;
|
|
2724
|
+
/** Video width in pixels (video only). */
|
|
2725
|
+
videoWidth?: number;
|
|
2726
|
+
/** Video height in pixels (video only). */
|
|
2727
|
+
videoHeight?: number;
|
|
2728
|
+
/** MIME type / codec string reported by the browser. */
|
|
2729
|
+
codecInfo?: string;
|
|
2730
|
+
}
|
|
2731
|
+
/**
|
|
2732
|
+
* A closed-caption / subtitle track associated with a media element.
|
|
2733
|
+
*
|
|
2734
|
+
* @example
|
|
2735
|
+
* ```ts
|
|
2736
|
+
* const track: MediaCaptionTrack = {
|
|
2737
|
+
* id: "t1",
|
|
2738
|
+
* label: "English",
|
|
2739
|
+
* language: "en",
|
|
2740
|
+
* kind: "subtitles",
|
|
2741
|
+
* isDefault: true,
|
|
2742
|
+
* };
|
|
2743
|
+
* // => satisfies MediaCaptionTrack
|
|
2744
|
+
* ```
|
|
2745
|
+
*/
|
|
2746
|
+
interface MediaCaptionTrack {
|
|
2747
|
+
/** Unique ID for this track. */
|
|
2748
|
+
id: string;
|
|
2749
|
+
/** Human-readable label (e.g. "English", "Spanish"). */
|
|
2750
|
+
label: string;
|
|
2751
|
+
/** BCP-47 language code (e.g. "en", "es"). */
|
|
2752
|
+
language: string;
|
|
2753
|
+
/** Track kind: subtitles, captions, or descriptions. */
|
|
2754
|
+
kind: 'subtitles' | 'captions' | 'descriptions';
|
|
2755
|
+
/** Data URL or path to the VTT/SRT content within the PPTX archive. */
|
|
2756
|
+
src?: string;
|
|
2757
|
+
/** Inline VTT content (for embedded captions). */
|
|
2758
|
+
content?: string;
|
|
2759
|
+
/** Whether this track is the default/active one. */
|
|
2760
|
+
isDefault?: boolean;
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2763
|
+
/**
|
|
2764
|
+
* SmartArt node types: per-run text, per-node visual override, and the
|
|
2765
|
+
* data-model node itself. Split out of `smart-art.ts` to keep each type file
|
|
2766
|
+
* within the project's per-file line budget. Re-exported from `smart-art.ts`
|
|
2767
|
+
* (and thus the `types` barrel) for backward compatibility, so existing
|
|
2768
|
+
* imports of these symbols continue to work unchanged.
|
|
2769
|
+
*
|
|
2770
|
+
* @module pptx-types/smart-art-node
|
|
2771
|
+
*/
|
|
2772
|
+
/**
|
|
2773
|
+
* A single run of text inside a SmartArt node, capturing the run text and the
|
|
2774
|
+
* raw `a:rPr` run-properties object verbatim so per-run formatting (bold,
|
|
2775
|
+
* colour, size, etc.) survives a load -> edit -> save round-trip instead of
|
|
2776
|
+
* collapsing to a single unstyled run.
|
|
2777
|
+
*
|
|
2778
|
+
* @example
|
|
2779
|
+
* ```ts
|
|
2780
|
+
* const run: PptxSmartArtTextRun = {
|
|
2781
|
+
* text: "Bold",
|
|
2782
|
+
* rPr: { "@_b": "1", "@_lang": "en-US" },
|
|
2783
|
+
* };
|
|
2784
|
+
* // => satisfies PptxSmartArtTextRun
|
|
2785
|
+
* ```
|
|
2786
|
+
*/
|
|
2787
|
+
interface PptxSmartArtTextRun {
|
|
2788
|
+
/** Run text content. */
|
|
2789
|
+
text: string;
|
|
2790
|
+
/**
|
|
2791
|
+
* Raw parsed `a:rPr` run-properties object, preserved verbatim for
|
|
2792
|
+
* round-trip. Untyped XML, hence the loose record shape.
|
|
2793
|
+
*/
|
|
2794
|
+
rPr?: Record<string, unknown>;
|
|
2795
|
+
}
|
|
2796
|
+
/**
|
|
2797
|
+
* Per-node visual override for a SmartArt node.
|
|
2798
|
+
*
|
|
2799
|
+
* Captures the individual fill / line / font colour and the bold / italic
|
|
2800
|
+
* emphasis a user has set on one specific node, independent of the diagram's
|
|
2801
|
+
* colour scheme and quick style. All colours are hex strings (e.g. "#FF0000").
|
|
2802
|
+
* Every field is optional: only the overridden aspects are carried, so an
|
|
2803
|
+
* empty object means "no per-node override".
|
|
2804
|
+
*
|
|
2805
|
+
* The parser reads these from the data point's `spPr` solid fill / line colour
|
|
2806
|
+
* and the first run's `rPr` (b / i / solidFill) when present, and the save path
|
|
2807
|
+
* writes them back so the override survives a load -> edit -> save round-trip.
|
|
2808
|
+
*
|
|
2809
|
+
* @example
|
|
2810
|
+
* ```ts
|
|
2811
|
+
* const style: PptxSmartArtNodeStyle = {
|
|
2812
|
+
* fillColor: "#FF0000",
|
|
2813
|
+
* fontColor: "#FFFFFF",
|
|
2814
|
+
* bold: true,
|
|
2815
|
+
* };
|
|
2816
|
+
* // => satisfies PptxSmartArtNodeStyle
|
|
2817
|
+
* ```
|
|
2818
|
+
*/
|
|
2819
|
+
interface PptxSmartArtNodeStyle {
|
|
2820
|
+
/** Solid fill colour override (hex, e.g. "#4F81BD"). */
|
|
2821
|
+
fillColor?: string;
|
|
2822
|
+
/** Outline / line colour override (hex). */
|
|
2823
|
+
lineColor?: string;
|
|
2824
|
+
/** Text (font) colour override (hex). */
|
|
2825
|
+
fontColor?: string;
|
|
2826
|
+
/** Bold emphasis override for the node's runs. */
|
|
2827
|
+
bold?: boolean;
|
|
2828
|
+
/** Italic emphasis override for the node's runs. */
|
|
2829
|
+
italic?: boolean;
|
|
2830
|
+
}
|
|
2831
|
+
/**
|
|
2832
|
+
* A single node in the SmartArt data model.
|
|
2833
|
+
*
|
|
2834
|
+
* @example
|
|
2835
|
+
* ```ts
|
|
2836
|
+
* const node: PptxSmartArtNode = {
|
|
2837
|
+
* id: "1",
|
|
2838
|
+
* text: "CEO",
|
|
2839
|
+
* children: [
|
|
2840
|
+
* { id: "2", text: "VP Marketing", parentId: "1" },
|
|
2841
|
+
* { id: "3", text: "VP Engineering", parentId: "1" },
|
|
2842
|
+
* ],
|
|
2843
|
+
* };
|
|
2844
|
+
* // => satisfies PptxSmartArtNode
|
|
2845
|
+
* ```
|
|
2846
|
+
*/
|
|
2847
|
+
interface PptxSmartArtNode {
|
|
2848
|
+
id: string;
|
|
2849
|
+
text: string;
|
|
2850
|
+
parentId?: string;
|
|
2851
|
+
children?: PptxSmartArtNode[];
|
|
2852
|
+
/** Node type from `@_type` attribute (e.g. "doc", "node", "asst", "pres"). */
|
|
2853
|
+
nodeType?: string;
|
|
2854
|
+
/**
|
|
2855
|
+
* Per-run text + run-properties for the node's first paragraph, captured at
|
|
2856
|
+
* parse time. When the joined run text still equals {@link text} (the node
|
|
2857
|
+
* was not edited, or was edited only in ways that preserve the run split),
|
|
2858
|
+
* the save path rebuilds the paragraph from these runs so per-run rich text
|
|
2859
|
+
* is not flattened. When {@link text} diverges, the runs are ignored.
|
|
2860
|
+
*/
|
|
2861
|
+
runs?: PptxSmartArtTextRun[];
|
|
2862
|
+
/**
|
|
2863
|
+
* Optional per-node visual override (fill / line / font colour, bold /
|
|
2864
|
+
* italic). Read at parse time from the point's `spPr` / first-run `rPr`, set
|
|
2865
|
+
* by the editing op, honoured by the render path, and written back on save so
|
|
2866
|
+
* it round-trips.
|
|
2867
|
+
*/
|
|
2868
|
+
style?: PptxSmartArtNodeStyle;
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
/**
|
|
2872
|
+
* SmartArt types: layout categories, layout presets, colour schemes,
|
|
2873
|
+
* data-model nodes/connections, drawing shapes, chrome, and the composite
|
|
2874
|
+
* `PptxSmartArtData`.
|
|
2875
|
+
*
|
|
2876
|
+
* @module pptx-types/smart-art
|
|
2877
|
+
*/
|
|
2878
|
+
|
|
2879
|
+
/**
|
|
2880
|
+
* Resolved SmartArt layout category.
|
|
2881
|
+
*
|
|
2882
|
+
* @example
|
|
2883
|
+
* ```ts
|
|
2884
|
+
* const cat: SmartArtLayoutType = "hierarchy";
|
|
2885
|
+
* // => "hierarchy" — one of: "list" | "process" | "cycle" | "hierarchy" | "relationship" | …
|
|
2886
|
+
* ```
|
|
2887
|
+
*/
|
|
2888
|
+
type SmartArtLayoutType = 'list' | 'process' | 'cycle' | 'hierarchy' | 'relationship' | 'matrix' | 'pyramid' | 'funnel' | 'gear' | 'target' | 'timeline' | 'venn' | 'chevron' | 'bending' | 'unknown';
|
|
2889
|
+
/**
|
|
2890
|
+
* Named SmartArt layout presets for creation (subset of PowerPoint layouts).
|
|
2891
|
+
*
|
|
2892
|
+
* @example
|
|
2893
|
+
* ```ts
|
|
2894
|
+
* const layout: SmartArtLayout = "hierarchy";
|
|
2895
|
+
* // => "hierarchy" — one of: "basicBlockList" | "alternatingHexagons" | "hierarchy" | …
|
|
2896
|
+
* ```
|
|
2897
|
+
*/
|
|
2898
|
+
type SmartArtLayout = 'basicBlockList' | 'alternatingHexagons' | 'basicChevronProcess' | 'basicCycle' | 'basicPie' | 'basicRadial' | 'basicVenn' | 'continuousBlockProcess' | 'convergingRadial' | 'hierarchy' | 'horizontalBulletList' | 'linearVenn' | 'segmentedProcess' | 'stackedList' | 'tableList' | 'trapezoidList' | 'upwardArrow' | 'basicFunnel' | 'basicTarget' | 'interlockingGears' | 'basicTimeline' | 'basicMatrix' | 'basicPyramid' | 'invertedPyramid' | 'bendingProcess' | 'stepDownProcess' | 'alternatingFlow' | 'descendingProcess' | 'pictureAccentList' | 'verticalBlockList' | 'groupedList' | 'pyramidList' | 'horizontalPictureList' | 'accentProcess' | 'verticalChevronList';
|
|
2899
|
+
/**
|
|
2900
|
+
* SmartArt colour scheme presets.
|
|
2901
|
+
*
|
|
2902
|
+
* @example
|
|
2903
|
+
* ```ts
|
|
2904
|
+
* const scheme: SmartArtColorScheme = "colorful1";
|
|
2905
|
+
* // => "colorful1" — one of: "colorful1" | "colorful2" | "colorful3" | "monochromatic1" | "monochromatic2"
|
|
2906
|
+
* ```
|
|
2907
|
+
*/
|
|
2908
|
+
type SmartArtColorScheme = 'colorful1' | 'colorful2' | 'colorful3' | 'monochromatic1' | 'monochromatic2';
|
|
2909
|
+
/**
|
|
2910
|
+
* SmartArt visual style intensity.
|
|
2911
|
+
*
|
|
2912
|
+
* @example
|
|
2913
|
+
* ```ts
|
|
2914
|
+
* const style: SmartArtStyle = "moderate";
|
|
2915
|
+
* // => "moderate" — one of: "flat" | "moderate" | "intense"
|
|
2916
|
+
* ```
|
|
2917
|
+
*/
|
|
2918
|
+
type SmartArtStyle = 'flat' | 'moderate' | 'intense';
|
|
2919
|
+
/**
|
|
2920
|
+
* A connection between two SmartArt data-model nodes.
|
|
2921
|
+
*
|
|
2922
|
+
* @example
|
|
2923
|
+
* ```ts
|
|
2924
|
+
* const conn: PptxSmartArtConnection = {
|
|
2925
|
+
* sourceId: "1",
|
|
2926
|
+
* destId: "2",
|
|
2927
|
+
* type: "parOf",
|
|
2928
|
+
* };
|
|
2929
|
+
* // => satisfies PptxSmartArtConnection
|
|
2930
|
+
* ```
|
|
2931
|
+
*/
|
|
2932
|
+
interface PptxSmartArtConnection {
|
|
2933
|
+
/** Model ID of the source node. */
|
|
2934
|
+
sourceId: string;
|
|
2935
|
+
/** Model ID of the destination node. */
|
|
2936
|
+
destId: string;
|
|
2937
|
+
/** Connection type (e.g. "parOf", "presOf", "sibTrans"). */
|
|
2938
|
+
type?: string;
|
|
2939
|
+
/** Source index for ordering sibling connections. */
|
|
2940
|
+
srcOrd?: number;
|
|
2941
|
+
/** Destination index for ordering. */
|
|
2942
|
+
destOrd?: number;
|
|
2943
|
+
}
|
|
2944
|
+
/**
|
|
2945
|
+
* A pre-computed shape from `ppt/diagrams/drawing*.xml`.
|
|
2946
|
+
*
|
|
2947
|
+
* @example
|
|
2948
|
+
* ```ts
|
|
2949
|
+
* const shape: PptxSmartArtDrawingShape = {
|
|
2950
|
+
* id: "s1",
|
|
2951
|
+
* shapeType: "roundRect",
|
|
2952
|
+
* x: 100, y: 50, width: 200, height: 80,
|
|
2953
|
+
* fillColor: "#4F81BD",
|
|
2954
|
+
* text: "CEO",
|
|
2955
|
+
* };
|
|
2956
|
+
* // => satisfies PptxSmartArtDrawingShape
|
|
2957
|
+
* ```
|
|
2958
|
+
*/
|
|
2959
|
+
interface PptxSmartArtDrawingShape {
|
|
2960
|
+
/** Shape ID within the drawing. */
|
|
2961
|
+
id: string;
|
|
2962
|
+
/** Preset geometry type (e.g. "roundRect", "ellipse"). */
|
|
2963
|
+
shapeType?: string;
|
|
2964
|
+
/** Position and size in EMU-based pixels. */
|
|
2965
|
+
x: number;
|
|
2966
|
+
y: number;
|
|
2967
|
+
width: number;
|
|
2968
|
+
height: number;
|
|
2969
|
+
/** Rotation in degrees. */
|
|
2970
|
+
rotation?: number;
|
|
2971
|
+
/** Skew along the X axis in degrees. */
|
|
2972
|
+
skewX?: number;
|
|
2973
|
+
/** Skew along the Y axis in degrees. */
|
|
2974
|
+
skewY?: number;
|
|
2975
|
+
/** Solid fill colour (hex). */
|
|
2976
|
+
fillColor?: string;
|
|
2977
|
+
/** Stroke colour (hex). */
|
|
2978
|
+
strokeColor?: string;
|
|
2979
|
+
/** Stroke width in points. */
|
|
2980
|
+
strokeWidth?: number;
|
|
2981
|
+
/** Text content of the shape. */
|
|
2982
|
+
text?: string;
|
|
2983
|
+
/** Font size in points. */
|
|
2984
|
+
fontSize?: number;
|
|
2985
|
+
/** Font colour (hex). */
|
|
2986
|
+
fontColor?: string;
|
|
2987
|
+
}
|
|
2988
|
+
/**
|
|
2989
|
+
* Background / outline extracted from `dgm:bg` and `dgm:whole`.
|
|
2990
|
+
*
|
|
2991
|
+
* @example
|
|
2992
|
+
* ```ts
|
|
2993
|
+
* const chrome: PptxSmartArtChrome = {
|
|
2994
|
+
* backgroundColor: "#F0F0F0",
|
|
2995
|
+
* outlineColor: "#333333",
|
|
2996
|
+
* outlineWidth: 1,
|
|
2997
|
+
* };
|
|
2998
|
+
* // => satisfies PptxSmartArtChrome
|
|
2999
|
+
* ```
|
|
3000
|
+
*/
|
|
3001
|
+
interface PptxSmartArtChrome {
|
|
3002
|
+
/** Background fill colour (hex). */
|
|
3003
|
+
backgroundColor?: string;
|
|
3004
|
+
/** Outline stroke colour (hex). */
|
|
3005
|
+
outlineColor?: string;
|
|
3006
|
+
/** Outline stroke width in points. */
|
|
3007
|
+
outlineWidth?: number;
|
|
3008
|
+
}
|
|
3009
|
+
/**
|
|
3010
|
+
* Colour transform entry from `ppt/diagrams/colors*.xml`.
|
|
3011
|
+
*
|
|
3012
|
+
* @example
|
|
3013
|
+
* ```ts
|
|
3014
|
+
* const transform: PptxSmartArtColorTransform = {
|
|
3015
|
+
* name: "Colorful - Accent Colors",
|
|
3016
|
+
* fillColors: ["#4F81BD", "#C0504D", "#9BBB59"],
|
|
3017
|
+
* lineColors: ["#385D8A", "#8C3836", "#71893F"],
|
|
3018
|
+
* };
|
|
3019
|
+
* // => satisfies PptxSmartArtColorTransform
|
|
3020
|
+
* ```
|
|
3021
|
+
*/
|
|
3022
|
+
interface PptxSmartArtColorTransform {
|
|
3023
|
+
/** Colour scheme name / title. */
|
|
3024
|
+
name?: string;
|
|
3025
|
+
/** Ordered list of fill colours (hex) for each node. */
|
|
3026
|
+
fillColors: string[];
|
|
3027
|
+
/** Ordered list of line colours (hex). */
|
|
3028
|
+
lineColors: string[];
|
|
3029
|
+
}
|
|
3030
|
+
/**
|
|
3031
|
+
* Style entry from `ppt/diagrams/quickStyles*.xml`.
|
|
3032
|
+
*
|
|
3033
|
+
* @example
|
|
3034
|
+
* ```ts
|
|
3035
|
+
* const qs: PptxSmartArtQuickStyle = {
|
|
3036
|
+
* name: "Moderate Effect",
|
|
3037
|
+
* effectIntensity: "moderate",
|
|
3038
|
+
* };
|
|
3039
|
+
* // => satisfies PptxSmartArtQuickStyle
|
|
3040
|
+
* ```
|
|
3041
|
+
*/
|
|
3042
|
+
interface PptxSmartArtQuickStyle {
|
|
3043
|
+
/** Style name / title. */
|
|
3044
|
+
name?: string;
|
|
3045
|
+
/** Effect intensity identifier (e.g. "subtle", "moderate", "intense"). */
|
|
3046
|
+
effectIntensity?: string;
|
|
3047
|
+
}
|
|
3048
|
+
/**
|
|
3049
|
+
* Complete parsed SmartArt data for a {@link SmartArtPptxElement}.
|
|
3050
|
+
*
|
|
3051
|
+
* @example
|
|
3052
|
+
* ```ts
|
|
3053
|
+
* const data: PptxSmartArtData = {
|
|
3054
|
+
* resolvedLayoutType: "hierarchy",
|
|
3055
|
+
* layout: "hierarchy",
|
|
3056
|
+
* colorScheme: "colorful1",
|
|
3057
|
+
* style: "moderate",
|
|
3058
|
+
* nodes: [
|
|
3059
|
+
* { id: "1", text: "CEO", children: [
|
|
3060
|
+
* { id: "2", text: "VP Marketing", parentId: "1" },
|
|
3061
|
+
* ]},
|
|
3062
|
+
* ],
|
|
3063
|
+
* };
|
|
3064
|
+
* // => satisfies PptxSmartArtData
|
|
3065
|
+
* ```
|
|
3066
|
+
*/
|
|
3067
|
+
interface PptxSmartArtData {
|
|
3068
|
+
layoutType?: string;
|
|
3069
|
+
resolvedLayoutType?: SmartArtLayoutType;
|
|
3070
|
+
/** Named layout preset (used when creating new SmartArt). */
|
|
3071
|
+
layout?: SmartArtLayout;
|
|
3072
|
+
/** Colour scheme for the SmartArt graphic. */
|
|
3073
|
+
colorScheme?: SmartArtColorScheme;
|
|
3074
|
+
/** Visual style intensity. */
|
|
3075
|
+
style?: SmartArtStyle;
|
|
3076
|
+
nodes: PptxSmartArtNode[];
|
|
3077
|
+
/** Connections between data-model nodes. */
|
|
3078
|
+
connections?: PptxSmartArtConnection[];
|
|
3079
|
+
/** Pre-computed shapes from `ppt/diagrams/drawing*.xml`. */
|
|
3080
|
+
drawingShapes?: PptxSmartArtDrawingShape[];
|
|
3081
|
+
/** Background and outline chrome from `dgm:bg` / `dgm:whole`. */
|
|
3082
|
+
chrome?: PptxSmartArtChrome;
|
|
3083
|
+
/** Colour transform from `ppt/diagrams/colors*.xml`. */
|
|
3084
|
+
colorTransform?: PptxSmartArtColorTransform;
|
|
3085
|
+
/** Quick style from `ppt/diagrams/quickStyles*.xml`. */
|
|
3086
|
+
quickStyle?: PptxSmartArtQuickStyle;
|
|
3087
|
+
/** Relationship ID for the diagram data part (for round-trip save). */
|
|
3088
|
+
dataRelId?: string;
|
|
3089
|
+
/** Relationship ID for the drawing part. */
|
|
3090
|
+
drawingRelId?: string;
|
|
3091
|
+
/** Relationship ID for the colours part. */
|
|
3092
|
+
colorsRelId?: string;
|
|
3093
|
+
/** Relationship ID for the quick-styles part. */
|
|
3094
|
+
styleRelId?: string;
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
/**
|
|
3098
|
+
* Table types: cell styling, cell data, rows, table data, and the parsed
|
|
3099
|
+
* table style map from `ppt/tableStyles.xml`.
|
|
3100
|
+
*
|
|
3101
|
+
* @module pptx-types/table
|
|
3102
|
+
*/
|
|
3103
|
+
/**
|
|
3104
|
+
* Per-cell visual style for a table cell.
|
|
3105
|
+
*
|
|
3106
|
+
* All fields are optional — unset values inherit from the table style.
|
|
3107
|
+
*
|
|
3108
|
+
* @example
|
|
3109
|
+
* ```ts
|
|
3110
|
+
* const header: PptxTableCellStyle = {
|
|
3111
|
+
* bold: true,
|
|
3112
|
+
* fontSize: 14,
|
|
3113
|
+
* color: "#FFFFFF",
|
|
3114
|
+
* backgroundColor: "#0055AA",
|
|
3115
|
+
* align: "center",
|
|
3116
|
+
* };
|
|
3117
|
+
* // => satisfies PptxTableCellStyle
|
|
3118
|
+
* ```
|
|
3119
|
+
*/
|
|
3120
|
+
interface PptxTableCellStyle {
|
|
3121
|
+
fontSize?: number;
|
|
3122
|
+
bold?: boolean;
|
|
3123
|
+
italic?: boolean;
|
|
3124
|
+
underline?: boolean;
|
|
3125
|
+
color?: string;
|
|
3126
|
+
/**
|
|
3127
|
+
* Raw XML colour-choice node preserved from `a:tc/a:txBody/.../a:rPr/a:solidFill`
|
|
3128
|
+
* for round-trip serialisation. Currently unused by the cell-level writer
|
|
3129
|
+
* (cell text colour falls through `writeCellTextFormatting`), reserved for
|
|
3130
|
+
* future expansion alongside the run-properties round-trip path.
|
|
3131
|
+
*/
|
|
3132
|
+
colorXml?: XmlObject;
|
|
3133
|
+
backgroundColor?: string;
|
|
3134
|
+
/**
|
|
3135
|
+
* Raw XML colour-choice node preserved from cell `a:tcPr/a:solidFill` for
|
|
3136
|
+
* round-trip serialisation. Re-emitted verbatim when the resolved
|
|
3137
|
+
* {@link backgroundColor} still matches the original colour.
|
|
3138
|
+
*/
|
|
3139
|
+
backgroundColorXml?: XmlObject;
|
|
3140
|
+
borderColor?: string;
|
|
3141
|
+
/** Top border width in px. */
|
|
3142
|
+
borderTopWidth?: number;
|
|
3143
|
+
/** Bottom border width in px. */
|
|
3144
|
+
borderBottomWidth?: number;
|
|
3145
|
+
/** Left border width in px. */
|
|
3146
|
+
borderLeftWidth?: number;
|
|
3147
|
+
/** Right border width in px. */
|
|
3148
|
+
borderRightWidth?: number;
|
|
3149
|
+
/** Top border color as hex. */
|
|
3150
|
+
borderTopColor?: string;
|
|
3151
|
+
/** Bottom border color as hex. */
|
|
3152
|
+
borderBottomColor?: string;
|
|
3153
|
+
/** Left border color as hex. */
|
|
3154
|
+
borderLeftColor?: string;
|
|
3155
|
+
/** Right border color as hex. */
|
|
3156
|
+
borderRightColor?: string;
|
|
3157
|
+
align?: 'left' | 'center' | 'right' | 'justify';
|
|
3158
|
+
vAlign?: 'top' | 'middle' | 'bottom';
|
|
3159
|
+
/** Text direction from `a:tcPr/@vert` (spec values from CT_TextVerticalType). */
|
|
3160
|
+
textDirection?: 'vert' | 'vert270' | 'eaVert' | 'wordArtVert' | 'wordArtVertRtl' | 'mongolianVert';
|
|
3161
|
+
/** Cell left margin in px (from a:tcPr > a:tcMar > a:marL). */
|
|
3162
|
+
marginLeft?: number;
|
|
3163
|
+
/** Cell right margin in px. */
|
|
3164
|
+
marginRight?: number;
|
|
3165
|
+
/** Cell top margin in px. */
|
|
3166
|
+
marginTop?: number;
|
|
3167
|
+
/** Cell bottom margin in px. */
|
|
3168
|
+
marginBottom?: number;
|
|
3169
|
+
/** Diagonal border top-left to bottom-right color. */
|
|
3170
|
+
borderDiagDownColor?: string;
|
|
3171
|
+
/** Diagonal border top-left to bottom-right width in px. */
|
|
3172
|
+
borderDiagDownWidth?: number;
|
|
3173
|
+
/** Diagonal border bottom-left to top-right color. */
|
|
3174
|
+
borderDiagUpColor?: string;
|
|
3175
|
+
/** Diagonal border bottom-left to top-right width in px. */
|
|
3176
|
+
borderDiagUpWidth?: number;
|
|
3177
|
+
/** Table cell border dash style (legacy single value). */
|
|
3178
|
+
borderDash?: string;
|
|
3179
|
+
/** Per-edge border dash styles. */
|
|
3180
|
+
borderTopDash?: string;
|
|
3181
|
+
borderBottomDash?: string;
|
|
3182
|
+
borderLeftDash?: string;
|
|
3183
|
+
borderRightDash?: string;
|
|
3184
|
+
/** Cell text shadow colour. */
|
|
3185
|
+
textShadowColor?: string;
|
|
3186
|
+
/** Cell text shadow blur radius in px. */
|
|
3187
|
+
textShadowBlur?: number;
|
|
3188
|
+
/** Cell text shadow horizontal offset in px. */
|
|
3189
|
+
textShadowOffsetX?: number;
|
|
3190
|
+
/** Cell text shadow vertical offset in px. */
|
|
3191
|
+
textShadowOffsetY?: number;
|
|
3192
|
+
/** Cell text shadow opacity (0-1). */
|
|
3193
|
+
textShadowOpacity?: number;
|
|
3194
|
+
/** Cell text glow colour. */
|
|
3195
|
+
textGlowColor?: string;
|
|
3196
|
+
/** Cell text glow radius in px. */
|
|
3197
|
+
textGlowRadius?: number;
|
|
3198
|
+
/** Cell text glow opacity (0-1). */
|
|
3199
|
+
textGlowOpacity?: number;
|
|
3200
|
+
/** Cell fill mode: solid, gradient, pattern, or none. */
|
|
3201
|
+
fillMode?: 'solid' | 'gradient' | 'pattern' | 'none';
|
|
3202
|
+
/** Gradient fill stops (colours with positions). */
|
|
3203
|
+
gradientFillStops?: Array<{
|
|
3204
|
+
color: string;
|
|
3205
|
+
position: number;
|
|
3206
|
+
opacity?: number;
|
|
3207
|
+
}>;
|
|
3208
|
+
/** Gradient angle in degrees. */
|
|
3209
|
+
gradientFillAngle?: number;
|
|
3210
|
+
/** Gradient type: linear or radial. */
|
|
3211
|
+
gradientFillType?: 'linear' | 'radial';
|
|
3212
|
+
/** Path gradient sub-type. */
|
|
3213
|
+
gradientFillPathType?: 'circle' | 'rect' | 'shape';
|
|
3214
|
+
/** Focal point for radial gradients (0–1 fractions). */
|
|
3215
|
+
gradientFillFocalPoint?: {
|
|
3216
|
+
x: number;
|
|
3217
|
+
y: number;
|
|
3218
|
+
};
|
|
3219
|
+
/** Raw fillToRect LTRB values (0–1 fractions) for gradient sizing. */
|
|
3220
|
+
gradientFillFillToRect?: {
|
|
3221
|
+
l: number;
|
|
3222
|
+
t: number;
|
|
3223
|
+
r: number;
|
|
3224
|
+
b: number;
|
|
3225
|
+
};
|
|
3226
|
+
/** Pre-computed CSS gradient string for rendering. */
|
|
3227
|
+
gradientFillCss?: string;
|
|
3228
|
+
/** Pattern fill preset name (e.g. "ltDnDiag"). */
|
|
3229
|
+
patternFillPreset?: string;
|
|
3230
|
+
/** Pattern fill foreground colour. */
|
|
3231
|
+
patternFillForeground?: string;
|
|
3232
|
+
/** Pattern fill background colour. */
|
|
3233
|
+
patternFillBackground?: string;
|
|
3234
|
+
}
|
|
3235
|
+
/**
|
|
3236
|
+
* A single table cell with text content, optional style, and merge info.
|
|
3237
|
+
*
|
|
3238
|
+
* @example
|
|
3239
|
+
* ```ts
|
|
3240
|
+
* const cell: PptxTableCell = {
|
|
3241
|
+
* text: "$1.5M",
|
|
3242
|
+
* style: { bold: true, align: "right" },
|
|
3243
|
+
* gridSpan: 1,
|
|
3244
|
+
* };
|
|
3245
|
+
* // => satisfies PptxTableCell
|
|
3246
|
+
* ```
|
|
3247
|
+
*/
|
|
3248
|
+
interface PptxTableCell {
|
|
3249
|
+
text: string;
|
|
3250
|
+
style?: PptxTableCellStyle;
|
|
3251
|
+
/** Column span (defaults to 1). */
|
|
3252
|
+
gridSpan?: number;
|
|
3253
|
+
/** Row span (defaults to 1). */
|
|
3254
|
+
rowSpan?: number;
|
|
3255
|
+
/** Whether this cell is merged vertically with the cell above. */
|
|
3256
|
+
vMerge?: boolean;
|
|
3257
|
+
/** Whether this cell is horizontally merged with the cell to the left (gridSpan continuation). */
|
|
3258
|
+
hMerge?: boolean;
|
|
3259
|
+
/**
|
|
3260
|
+
* Opaque round-trip storage for `a:tcPr` attributes that don't yet have
|
|
3261
|
+
* typed equivalents on {@link PptxTableCellStyle} (e.g. `horzOverflow`,
|
|
3262
|
+
* `anchorCtr`, `headers`, `hideSlicers`, `slicerCacheId`). Keys are the
|
|
3263
|
+
* raw XML attribute names without the `@_` prefix used by
|
|
3264
|
+
* fast-xml-parser. Re-emitted verbatim by the save writer when present.
|
|
3265
|
+
*/
|
|
3266
|
+
extraAttributes?: Record<string, string>;
|
|
3267
|
+
}
|
|
3268
|
+
/**
|
|
3269
|
+
* A single table row with an optional height and an array of cells.
|
|
3270
|
+
*
|
|
3271
|
+
* @example
|
|
3272
|
+
* ```ts
|
|
3273
|
+
* const row: PptxTableRow = {
|
|
3274
|
+
* height: 40,
|
|
3275
|
+
* cells: [
|
|
3276
|
+
* { text: "Name" },
|
|
3277
|
+
* { text: "Score" },
|
|
3278
|
+
* ],
|
|
3279
|
+
* };
|
|
3280
|
+
* // => satisfies PptxTableRow
|
|
3281
|
+
* ```
|
|
3282
|
+
*/
|
|
3283
|
+
interface PptxTableRow {
|
|
3284
|
+
/** Row height in px. */
|
|
3285
|
+
height?: number;
|
|
3286
|
+
cells: PptxTableCell[];
|
|
3287
|
+
}
|
|
3288
|
+
/**
|
|
3289
|
+
* Complete parsed table data for a {@link TablePptxElement}.
|
|
3290
|
+
*
|
|
3291
|
+
* Includes row/cell data, column widths, banding flags, and the applied
|
|
3292
|
+
* table style ID.
|
|
3293
|
+
*
|
|
3294
|
+
* @example
|
|
3295
|
+
* ```ts
|
|
3296
|
+
* const data: PptxTableData = {
|
|
3297
|
+
* rows: [
|
|
3298
|
+
* { cells: [{ text: "Product" }, { text: "Revenue" }] },
|
|
3299
|
+
* { cells: [{ text: "Widget A" }, { text: "$3.4M" }] },
|
|
3300
|
+
* ],
|
|
3301
|
+
* columnWidths: [0.6, 0.4],
|
|
3302
|
+
* firstRowHeader: true,
|
|
3303
|
+
* bandedRows: true,
|
|
3304
|
+
* };
|
|
3305
|
+
* // => satisfies PptxTableData
|
|
3306
|
+
* ```
|
|
3307
|
+
*/
|
|
3308
|
+
interface PptxTableData {
|
|
3309
|
+
rows: PptxTableRow[];
|
|
3310
|
+
/** Column widths as proportion of total (summing to 1). */
|
|
3311
|
+
columnWidths: number[];
|
|
3312
|
+
/** Whether the table has banded rows. */
|
|
3313
|
+
bandedRows?: boolean;
|
|
3314
|
+
/** Whether the first row is a header. */
|
|
3315
|
+
firstRowHeader?: boolean;
|
|
3316
|
+
/** Whether banded columns are enabled. */
|
|
3317
|
+
bandedColumns?: boolean;
|
|
3318
|
+
/** Whether the last row is styled as a total row. */
|
|
3319
|
+
lastRow?: boolean;
|
|
3320
|
+
/** Whether the first column is styled as a header column. */
|
|
3321
|
+
firstCol?: boolean;
|
|
3322
|
+
/** Whether the last column is styled specially. */
|
|
3323
|
+
lastCol?: boolean;
|
|
3324
|
+
/** Table style ID from `a:tblPr/a:tblStyle@val` or `a:tblPr@tblStyle`. */
|
|
3325
|
+
tableStyleId?: string;
|
|
3326
|
+
/** Number of rows per banding group (default 1). */
|
|
3327
|
+
bandRowCycle?: number;
|
|
3328
|
+
/** Number of columns per banding group (default 1). */
|
|
3329
|
+
bandColCycle?: number;
|
|
3330
|
+
/** Right-to-left table layout from `a:tblPr/@rtl`. */
|
|
3331
|
+
rtl?: boolean;
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
/**
|
|
3335
|
+
* A text box — a plain rectangle containing text, typically with no
|
|
3336
|
+
* visible fill or stroke.
|
|
3337
|
+
*
|
|
3338
|
+
* @example
|
|
3339
|
+
* ```ts
|
|
3340
|
+
* const title: TextPptxElement = {
|
|
3341
|
+
* type: "text",
|
|
3342
|
+
* id: "txt_1", x: 50, y: 30, width: 800, height: 60,
|
|
3343
|
+
* text: "Welcome",
|
|
3344
|
+
* textStyle: { fontSize: 36, bold: true },
|
|
3345
|
+
* };
|
|
3346
|
+
* // => satisfies TextPptxElement
|
|
3347
|
+
* ```
|
|
3348
|
+
*/
|
|
3349
|
+
interface TextPptxElement extends PptxElementBase, PptxTextProperties, PptxShapeProperties {
|
|
3350
|
+
type: 'text';
|
|
3351
|
+
}
|
|
3352
|
+
/**
|
|
3353
|
+
* A shape — may contain text and custom geometry (preset or freeform).
|
|
3354
|
+
*
|
|
3355
|
+
* @example
|
|
3356
|
+
* ```ts
|
|
3357
|
+
* const rect: ShapePptxElement = {
|
|
3358
|
+
* type: "shape",
|
|
3359
|
+
* id: "shp_1", x: 100, y: 200, width: 300, height: 150,
|
|
3360
|
+
* shapeType: "roundRect",
|
|
3361
|
+
* shapeStyle: { fillColor: "#00AA55" },
|
|
3362
|
+
* text: "OK",
|
|
3363
|
+
* };
|
|
3364
|
+
* // => satisfies ShapePptxElement
|
|
3365
|
+
* ```
|
|
3366
|
+
*/
|
|
3367
|
+
interface ShapePptxElement extends PptxElementBase, PptxTextProperties, PptxShapeProperties, PptxCustomPathProperties {
|
|
3368
|
+
type: 'shape';
|
|
3369
|
+
}
|
|
3370
|
+
/**
|
|
3371
|
+
* A connector (straight, bent, or curved line between shapes).
|
|
3372
|
+
*
|
|
3373
|
+
* Connector endpoints can snap to specific shapes via
|
|
3374
|
+
* `shapeStyle.connectorStartConnection` / `connectorEndConnection`.
|
|
3375
|
+
*
|
|
3376
|
+
* @example
|
|
3377
|
+
* ```ts
|
|
3378
|
+
* const line: ConnectorPptxElement = {
|
|
3379
|
+
* type: "connector",
|
|
3380
|
+
* id: "cxn_1", x: 100, y: 100, width: 200, height: 0,
|
|
3381
|
+
* shapeStyle: {
|
|
3382
|
+
* strokeColor: "#333",
|
|
3383
|
+
* connectorEndArrow: "triangle",
|
|
3384
|
+
* },
|
|
3385
|
+
* };
|
|
3386
|
+
* // => satisfies ConnectorPptxElement
|
|
3387
|
+
* ```
|
|
3388
|
+
*/
|
|
3389
|
+
interface ConnectorPptxElement extends PptxElementBase, PptxTextProperties, PptxShapeProperties {
|
|
3390
|
+
type: 'connector';
|
|
3391
|
+
}
|
|
3392
|
+
/**
|
|
3393
|
+
* An image element from an OOXML `<p:pic>` node with `type: "image"`.
|
|
3394
|
+
*
|
|
3395
|
+
* @example
|
|
3396
|
+
* ```ts
|
|
3397
|
+
* const img: ImagePptxElement = {
|
|
3398
|
+
* type: "image",
|
|
3399
|
+
* id: "img_1", x: 0, y: 0, width: 960, height: 540,
|
|
3400
|
+
* imagePath: "ppt/media/image1.png",
|
|
3401
|
+
* altText: "Background scenery",
|
|
3402
|
+
* };
|
|
3403
|
+
* // => satisfies ImagePptxElement
|
|
3404
|
+
* ```
|
|
3405
|
+
*/
|
|
3406
|
+
interface ImagePptxElement extends PptxElementBase, PptxShapeProperties, PptxCustomPathProperties, PptxImageProperties {
|
|
3407
|
+
type: 'image';
|
|
3408
|
+
}
|
|
3409
|
+
/**
|
|
3410
|
+
* A picture element from an OOXML `<p:pic>` node with `type: "picture"`.
|
|
3411
|
+
*
|
|
3412
|
+
* Functionally identical to {@link ImagePptxElement} but distinguished by
|
|
3413
|
+
* the `type` discriminant for semantic clarity.
|
|
3414
|
+
*/
|
|
3415
|
+
interface PicturePptxElement extends PptxElementBase, PptxShapeProperties, PptxCustomPathProperties, PptxImageProperties {
|
|
3416
|
+
type: 'picture';
|
|
3417
|
+
}
|
|
3418
|
+
/**
|
|
3419
|
+
* A single unrecognised `<a:graphicData>/<a:extLst>/<a:ext>` extension on a
|
|
3420
|
+
* graphicFrame, captured verbatim so the round-trip can preserve future or
|
|
3421
|
+
* vendor-specific markup that the parser doesn't yet understand.
|
|
3422
|
+
*
|
|
3423
|
+
* The XML is preserved as a fast-xml-parser object tree (the same shape as
|
|
3424
|
+
* `rawXml` on other elements) so the save layer can re-emit it through the
|
|
3425
|
+
* existing builder without lossy string manipulation.
|
|
3426
|
+
*/
|
|
3427
|
+
interface PptxGraphicFrameExtension {
|
|
3428
|
+
/** The `@_uri` attribute identifying the extension (e.g. `{C3CD43...}`). */
|
|
3429
|
+
uri: string;
|
|
3430
|
+
/** Parsed XML payload of the extension, suitable for re-serialization. */
|
|
3431
|
+
xml: XmlObject;
|
|
3432
|
+
}
|
|
3433
|
+
/**
|
|
3434
|
+
* A table embedded via a `<p:graphicFrame>`.
|
|
3435
|
+
*
|
|
3436
|
+
* @example
|
|
3437
|
+
* ```ts
|
|
3438
|
+
* const tbl: TablePptxElement = {
|
|
3439
|
+
* type: "table",
|
|
3440
|
+
* id: "tbl_1", x: 50, y: 200, width: 860, height: 300,
|
|
3441
|
+
* tableData: {
|
|
3442
|
+
* rows: [
|
|
3443
|
+
* { cells: [{ text: "Name" }, { text: "Score" }] },
|
|
3444
|
+
* { cells: [{ text: "Alice" }, { text: "95" }] },
|
|
3445
|
+
* ],
|
|
3446
|
+
* },
|
|
3447
|
+
* };
|
|
3448
|
+
* // => satisfies TablePptxElement
|
|
3449
|
+
* ```
|
|
3450
|
+
*/
|
|
3451
|
+
interface TablePptxElement extends PptxElementBase {
|
|
3452
|
+
type: 'table';
|
|
3453
|
+
/** Parsed table cell data for editing. */
|
|
3454
|
+
tableData?: PptxTableData;
|
|
3455
|
+
/**
|
|
3456
|
+
* Unrecognised extensions captured from `a:graphicData/a:extLst` so they
|
|
3457
|
+
* round-trip losslessly. See {@link PptxGraphicFrameExtension}.
|
|
3458
|
+
*/
|
|
3459
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3460
|
+
}
|
|
3461
|
+
/**
|
|
3462
|
+
* A chart embedded via a `<p:graphicFrame>`.
|
|
3463
|
+
*
|
|
3464
|
+
* Chart data is parsed from the related `chartN.xml` / `chartExN.xml`
|
|
3465
|
+
* parts inside the PPTX archive.
|
|
3466
|
+
*/
|
|
3467
|
+
interface ChartPptxElement extends PptxElementBase {
|
|
3468
|
+
type: 'chart';
|
|
3469
|
+
chartData?: PptxChartData;
|
|
3470
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3471
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3472
|
+
}
|
|
3473
|
+
/**
|
|
3474
|
+
* A SmartArt diagram embedded via a `<p:graphicFrame>`.
|
|
3475
|
+
*
|
|
3476
|
+
* SmartArt data is extracted from `dgm:dataModel` parts. The editor
|
|
3477
|
+
* renders a simplified view; full editing is not supported.
|
|
3478
|
+
*/
|
|
3479
|
+
interface SmartArtPptxElement extends PptxElementBase {
|
|
3480
|
+
type: 'smartArt';
|
|
3481
|
+
smartArtData?: PptxSmartArtData;
|
|
3482
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3483
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3484
|
+
}
|
|
3485
|
+
/**
|
|
3486
|
+
* Recognised OLE object application types derived from `progId` / `clsId`.
|
|
3487
|
+
*
|
|
3488
|
+
* Used to show type-specific icons and previews in the editor.
|
|
3489
|
+
*/
|
|
3490
|
+
type OleObjectType = 'excel' | 'word' | 'pdf' | 'visio' | 'mathtype' | 'package' | 'unknown';
|
|
3491
|
+
/**
|
|
3492
|
+
* An OLE (Object Linking and Embedding) object.
|
|
3493
|
+
*
|
|
3494
|
+
* OLE objects can be embedded Excel sheets, Word documents, PDFs, Visio
|
|
3495
|
+
* diagrams, MathType equations, or generic "packages". They carry a
|
|
3496
|
+
* preview image for display and optional binary data for extraction.
|
|
3497
|
+
*
|
|
3498
|
+
* @example
|
|
3499
|
+
* ```ts
|
|
3500
|
+
* const ole: OlePptxElement = {
|
|
3501
|
+
* type: "ole",
|
|
3502
|
+
* id: "ole_1", x: 100, y: 200, width: 400, height: 300,
|
|
3503
|
+
* oleObjectType: "excel",
|
|
3504
|
+
* oleProgId: "Excel.Sheet.12",
|
|
3505
|
+
* fileName: "budget.xlsx",
|
|
3506
|
+
* };
|
|
3507
|
+
* // => satisfies OlePptxElement
|
|
3508
|
+
* ```
|
|
3509
|
+
*/
|
|
3510
|
+
interface OlePptxElement extends PptxElementBase {
|
|
3511
|
+
type: 'ole';
|
|
3512
|
+
oleTarget?: string;
|
|
3513
|
+
oleProgId?: string;
|
|
3514
|
+
oleName?: string;
|
|
3515
|
+
/** CLSID of the OLE object (from `@_classid`). */
|
|
3516
|
+
oleClsId?: string;
|
|
3517
|
+
/** Detected application type (excel, word, pdf, etc.). */
|
|
3518
|
+
oleObjectType?: OleObjectType;
|
|
3519
|
+
/** File extension for the embedded binary (e.g. "xlsx", "docx"). */
|
|
3520
|
+
oleFileExtension?: string;
|
|
3521
|
+
/** Original file name when available. */
|
|
3522
|
+
fileName?: string;
|
|
3523
|
+
/** Whether this is a linked (vs. embedded) object. */
|
|
3524
|
+
isLinked?: boolean;
|
|
3525
|
+
/** External file path for linked OLE objects (TargetMode="External"). */
|
|
3526
|
+
externalPath?: string;
|
|
3527
|
+
/** Data-URL or path for the OLE preview image. */
|
|
3528
|
+
previewImage?: string;
|
|
3529
|
+
/** Decoded preview image as a data-URL. */
|
|
3530
|
+
previewImageData?: string;
|
|
3531
|
+
/** Whether the OLE object is shown as an icon (`p:oleObj/@showAsIcon`). */
|
|
3532
|
+
oleShowAsIcon?: boolean;
|
|
3533
|
+
/** Authored display width of the OLE object preview, in EMU (`@imgW`). */
|
|
3534
|
+
oleImgW?: number;
|
|
3535
|
+
/** Authored display height of the OLE object preview, in EMU (`@imgH`). */
|
|
3536
|
+
oleImgH?: number;
|
|
3537
|
+
/**
|
|
3538
|
+
* The recovered embedded payload as a data-URL (e.g.
|
|
3539
|
+
* `data:application/vnd...;base64,...`), suitable for download or
|
|
3540
|
+
* open-in-new-tab. For a generic "Package" OLE object this is the unwrapped
|
|
3541
|
+
* inner file; for a plain embedded file (e.g. `.xlsx`) it is that file
|
|
3542
|
+
* directly. Undefined when the embedding is missing or unreadable.
|
|
3543
|
+
*
|
|
3544
|
+
* Stored as a data-URL string to mirror how images store decoded bytes
|
|
3545
|
+
* ({@link ImagePptxElement.imageData}) and to stay serialization-safe.
|
|
3546
|
+
*/
|
|
3547
|
+
oleEmbeddedData?: string;
|
|
3548
|
+
/** Original file name of the embedded payload when recoverable. */
|
|
3549
|
+
oleEmbeddedFileName?: string;
|
|
3550
|
+
/** MIME type of the embedded payload, derived from its extension/ProgID. */
|
|
3551
|
+
oleEmbeddedMimeType?: string;
|
|
3552
|
+
/** Size of the embedded payload in bytes. */
|
|
3553
|
+
oleEmbeddedByteSize?: number;
|
|
3554
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3555
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3556
|
+
}
|
|
3557
|
+
/**
|
|
3558
|
+
* An audio or video media element.
|
|
3559
|
+
*
|
|
3560
|
+
* Media elements reference files inside the PPTX archive
|
|
3561
|
+
* (`mediaPath`) and may include trim points, poster frames, and
|
|
3562
|
+
* playback settings for presentation mode.
|
|
3563
|
+
*
|
|
3564
|
+
* @example
|
|
3565
|
+
* ```ts
|
|
3566
|
+
* const video: MediaPptxElement = {
|
|
3567
|
+
* type: "media",
|
|
3568
|
+
* id: "vid_1", x: 50, y: 100, width: 640, height: 360,
|
|
3569
|
+
* mediaType: "video",
|
|
3570
|
+
* mediaPath: "ppt/media/media1.mp4",
|
|
3571
|
+
* autoPlay: true,
|
|
3572
|
+
* volume: 0.8,
|
|
3573
|
+
* };
|
|
3574
|
+
* // => satisfies MediaPptxElement
|
|
3575
|
+
* ```
|
|
3576
|
+
*/
|
|
3577
|
+
interface MediaPptxElement extends PptxElementBase {
|
|
3578
|
+
type: 'media';
|
|
3579
|
+
mediaType?: PptxMediaType;
|
|
3580
|
+
mediaPath?: string;
|
|
3581
|
+
mediaData?: string;
|
|
3582
|
+
mediaMimeType?: string;
|
|
3583
|
+
/** Trim start in milliseconds (from p:cMediaNode p:cTn @st). */
|
|
3584
|
+
trimStartMs?: number;
|
|
3585
|
+
/** Trim end in milliseconds (from p:cMediaNode p:cTn @end). */
|
|
3586
|
+
trimEndMs?: number;
|
|
3587
|
+
/** Path to the poster/preview image inside the ZIP. */
|
|
3588
|
+
posterFramePath?: string;
|
|
3589
|
+
/** Base64 data-URL for the poster frame image. */
|
|
3590
|
+
posterFrameData?: string;
|
|
3591
|
+
/** Whether media should play full-screen during presentation. */
|
|
3592
|
+
fullScreen?: boolean;
|
|
3593
|
+
/** Whether media should loop continuously. */
|
|
3594
|
+
loop?: boolean;
|
|
3595
|
+
/** Fade-in duration in seconds. */
|
|
3596
|
+
fadeInDuration?: number;
|
|
3597
|
+
/** Fade-out duration in seconds. */
|
|
3598
|
+
fadeOutDuration?: number;
|
|
3599
|
+
/** Playback volume (0 to 1). */
|
|
3600
|
+
volume?: number;
|
|
3601
|
+
/** Whether media auto-plays on slide entry. */
|
|
3602
|
+
autoPlay?: boolean;
|
|
3603
|
+
/** Whether audio continues playing across slide transitions (presentation mode). */
|
|
3604
|
+
playAcrossSlides?: boolean;
|
|
3605
|
+
/** Hide the element when media is not actively playing. */
|
|
3606
|
+
hideWhenNotPlaying?: boolean;
|
|
3607
|
+
/** Named time bookmarks within the clip. */
|
|
3608
|
+
bookmarks?: MediaBookmark[];
|
|
3609
|
+
/** Playback speed multiplier (1 = normal, 2 = double, 0.5 = half). */
|
|
3610
|
+
playbackSpeed?: number;
|
|
3611
|
+
/** Runtime-extracted metadata (duration, resolution, codec). */
|
|
3612
|
+
metadata?: MediaMetadata;
|
|
3613
|
+
/** Closed caption / subtitle tracks. */
|
|
3614
|
+
captionTracks?: MediaCaptionTrack[];
|
|
3615
|
+
/** Whether the media source is missing/broken (file not found in archive). */
|
|
3616
|
+
mediaMissing?: boolean;
|
|
3617
|
+
/**
|
|
3618
|
+
* Whether the media is linked (external `r:link`) rather than embedded
|
|
3619
|
+
* (`r:embed`). Defaults to embedded when undefined.
|
|
3620
|
+
*/
|
|
3621
|
+
isLinked?: boolean;
|
|
3622
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3623
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3624
|
+
}
|
|
3625
|
+
/**
|
|
3626
|
+
* A group container that holds child elements.
|
|
3627
|
+
*
|
|
3628
|
+
* Children inherit the group’s transform, so moving/resizing the group
|
|
3629
|
+
* affects all children proportionally.
|
|
3630
|
+
*
|
|
3631
|
+
* @example
|
|
3632
|
+
* ```ts
|
|
3633
|
+
* const group: GroupPptxElement = {
|
|
3634
|
+
* type: "group",
|
|
3635
|
+
* id: "grp_1", x: 0, y: 0, width: 960, height: 540,
|
|
3636
|
+
* children: [textEl, shapeEl],
|
|
3637
|
+
* };
|
|
3638
|
+
* // => satisfies GroupPptxElement
|
|
3639
|
+
* ```
|
|
3640
|
+
*/
|
|
3641
|
+
interface GroupPptxElement extends PptxElementBase {
|
|
3642
|
+
type: 'group';
|
|
3643
|
+
/** Child elements contained within this group. */
|
|
3644
|
+
children: PptxElement[];
|
|
3645
|
+
/** Fill style extracted from the group's `p:grpSpPr`, used for `a:grpFill` inheritance. */
|
|
3646
|
+
groupFill?: ShapeStyle;
|
|
3647
|
+
}
|
|
3648
|
+
/**
|
|
3649
|
+
* A freehand ink / drawing stroke captured with a stylus or mouse.
|
|
3650
|
+
*
|
|
3651
|
+
* Ink strokes are stored as SVG path data strings. Each path may
|
|
3652
|
+
* have independent colour, width, and opacity.
|
|
3653
|
+
*/
|
|
3654
|
+
interface InkPptxElement extends PptxElementBase {
|
|
3655
|
+
type: 'ink';
|
|
3656
|
+
/** SVG path data for ink strokes. */
|
|
3657
|
+
inkPaths: string[];
|
|
3658
|
+
/** Per-path stroke colours. */
|
|
3659
|
+
inkColors?: string[];
|
|
3660
|
+
/** Per-path stroke widths. */
|
|
3661
|
+
inkWidths?: number[];
|
|
3662
|
+
/** Per-path opacities (0-1). */
|
|
3663
|
+
inkOpacities?: number[];
|
|
3664
|
+
/** Drawing tool used: pen, highlighter, or eraser. */
|
|
3665
|
+
inkTool?: 'pen' | 'highlighter' | 'eraser';
|
|
3666
|
+
/**
|
|
3667
|
+
* Per-path arrays of per-point pressure values (0-1).
|
|
3668
|
+
*
|
|
3669
|
+
* Each entry corresponds to the path at the same index in `inkPaths`.
|
|
3670
|
+
* Each inner array contains one pressure value per sampled point along
|
|
3671
|
+
* the stroke. When present, the renderer uses these values to produce
|
|
3672
|
+
* variable-width strokes that reflect stylus/pen pressure.
|
|
3673
|
+
*/
|
|
3674
|
+
inkPointPressures?: number[][];
|
|
3675
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3676
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3679
|
+
* A single ink stroke within a {@link ContentPartPptxElement}.
|
|
3680
|
+
*/
|
|
3681
|
+
interface ContentPartInkStroke {
|
|
3682
|
+
path: string;
|
|
3683
|
+
color: string;
|
|
3684
|
+
width: number;
|
|
3685
|
+
opacity: number;
|
|
3686
|
+
/**
|
|
3687
|
+
* Per-point pressure values (0-1) for this stroke.
|
|
3688
|
+
*
|
|
3689
|
+
* When present, the renderer uses these values to produce
|
|
3690
|
+
* variable-width strokes that reflect stylus/pen pressure.
|
|
3691
|
+
*/
|
|
3692
|
+
pressures?: number[];
|
|
3693
|
+
}
|
|
3694
|
+
/**
|
|
3695
|
+
* A content-part element wrapped in `mc:AlternateContent`.
|
|
3696
|
+
*
|
|
3697
|
+
* Typically contains ink strokes from modern PowerPoint pen/highlighter.
|
|
3698
|
+
*/
|
|
3699
|
+
interface ContentPartPptxElement extends PptxElementBase {
|
|
3700
|
+
type: 'contentPart';
|
|
3701
|
+
/** Ink strokes contained in this content part. */
|
|
3702
|
+
inkStrokes?: ContentPartInkStroke[];
|
|
3703
|
+
}
|
|
3704
|
+
/**
|
|
3705
|
+
* A Slide Zoom or Section Zoom element (PowerPoint Zoom Object).
|
|
3706
|
+
*
|
|
3707
|
+
* Zoom elements display a live thumbnail of the target slide and
|
|
3708
|
+
* navigate to it on click during presentation mode.
|
|
3709
|
+
*
|
|
3710
|
+
* @example
|
|
3711
|
+
* ```ts
|
|
3712
|
+
* const zoom: ZoomPptxElement = {
|
|
3713
|
+
* type: "zoom",
|
|
3714
|
+
* id: "zm_1", x: 300, y: 200, width: 200, height: 120,
|
|
3715
|
+
* zoomType: "slide",
|
|
3716
|
+
* targetSlideIndex: 5,
|
|
3717
|
+
* };
|
|
3718
|
+
* // => satisfies ZoomPptxElement
|
|
3719
|
+
* ```
|
|
3720
|
+
*/
|
|
3721
|
+
interface ZoomPptxElement extends PptxElementBase, PptxImageProperties {
|
|
3722
|
+
type: 'zoom';
|
|
3723
|
+
/** Type of zoom: slide-level or section-level. */
|
|
3724
|
+
zoomType: 'slide' | 'section';
|
|
3725
|
+
/** Zero-based index of the target slide. */
|
|
3726
|
+
targetSlideIndex: number;
|
|
3727
|
+
/** Section ID for section zoom. */
|
|
3728
|
+
targetSectionId?: string;
|
|
3729
|
+
}
|
|
3730
|
+
/**
|
|
3731
|
+
* A 3D model object embedded via `p16:model3D` inside an
|
|
3732
|
+
* `mc:AlternateContent` block (PowerPoint 365+).
|
|
3733
|
+
*
|
|
3734
|
+
* The element carries the path to the `.glb`/`.gltf` binary inside
|
|
3735
|
+
* the ZIP and a poster/fallback image for rendering in viewers that
|
|
3736
|
+
* do not support interactive 3D.
|
|
3737
|
+
*/
|
|
3738
|
+
interface Model3DPptxElement extends PptxElementBase, PptxImageProperties {
|
|
3739
|
+
type: 'model3d';
|
|
3740
|
+
/** Path to the 3D model file inside the ZIP. */
|
|
3741
|
+
modelPath?: string;
|
|
3742
|
+
/** Base64 data URL of the 3D model binary. */
|
|
3743
|
+
modelData?: string;
|
|
3744
|
+
/** MIME type of the model (e.g. "model/gltf-binary"). */
|
|
3745
|
+
modelMimeType?: string;
|
|
3746
|
+
/** Poster/preview image shown when 3D rendering is unavailable. */
|
|
3747
|
+
posterImage?: string;
|
|
3748
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3749
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3750
|
+
}
|
|
3751
|
+
/** An element whose type is not recognised by the parser. */
|
|
3752
|
+
interface UnknownPptxElement extends PptxElementBase {
|
|
3753
|
+
type: 'unknown';
|
|
3754
|
+
/** Unrecognised graphicFrame extLst extensions, captured verbatim for round-trip. */
|
|
3755
|
+
extensionXml?: PptxGraphicFrameExtension[];
|
|
3756
|
+
}
|
|
3757
|
+
/**
|
|
3758
|
+
* A single element on a PPTX slide.
|
|
3759
|
+
*
|
|
3760
|
+
* This is a **discriminated union** — narrow on `element.type` to access
|
|
3761
|
+
* variant-specific properties like `imageData` (image/picture), `pathData`
|
|
3762
|
+
* (shape), or `textSegments` (text/shape).
|
|
3763
|
+
*/
|
|
3764
|
+
type PptxElement = TextPptxElement | ShapePptxElement | ConnectorPptxElement | ImagePptxElement | PicturePptxElement | TablePptxElement | ChartPptxElement | SmartArtPptxElement | OlePptxElement | MediaPptxElement | GroupPptxElement | InkPptxElement | ContentPartPptxElement | ZoomPptxElement | Model3DPptxElement | UnknownPptxElement;
|
|
3765
|
+
/**
|
|
3766
|
+
* Per-part header/footer flags from `<p:hf>` (CT_HeaderFooter, ECMA-376
|
|
3767
|
+
* §19.3.1.21). Defaults are "all true" — fields are only set on the typed
|
|
3768
|
+
* model when they were explicitly read, so callers can distinguish "unset"
|
|
3769
|
+
* (preserve original XML) from "false" (override).
|
|
3770
|
+
*/
|
|
3771
|
+
interface PptxHeaderFooterFlags {
|
|
3772
|
+
/** `@hdr` — show header placeholder. Spec default: `true`. */
|
|
3773
|
+
hasHeader?: boolean;
|
|
3774
|
+
/** `@ftr` — show footer placeholder. Spec default: `true`. */
|
|
3775
|
+
hasFooter?: boolean;
|
|
3776
|
+
/** `@dt` — show date/time placeholder. Spec default: `true`. */
|
|
3777
|
+
hasDateTime?: boolean;
|
|
3778
|
+
/** `@sldNum` — show slide-number placeholder. Spec default: `true`. */
|
|
3779
|
+
hasSlideNumber?: boolean;
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3782
|
+
/**
|
|
3783
|
+
* Animation types: presets, triggers, timing, native parsed animation data,
|
|
3784
|
+
* and the high-level {@link PptxElementAnimation} associated with each element.
|
|
3785
|
+
*
|
|
3786
|
+
* @module pptx-types/animation
|
|
3787
|
+
*/
|
|
3788
|
+
|
|
3789
|
+
/**
|
|
3790
|
+
* Built-in animation preset names used for entrance, exit, and emphasis effects.
|
|
3791
|
+
*
|
|
3792
|
+
* @example
|
|
3793
|
+
* ```ts
|
|
3794
|
+
* const preset: PptxAnimationPreset = "fadeIn";
|
|
3795
|
+
* // => "fadeIn" — one of: none | fadeIn | flyIn | zoomIn | fadeOut | flyOut | zoomOut | spin | pulse | ...
|
|
3796
|
+
* ```
|
|
3797
|
+
*/
|
|
3798
|
+
type PptxAnimationPreset = 'none' | 'appear' | 'fadeIn' | 'flyIn' | 'zoomIn' | 'bounceIn' | 'wipeIn' | 'splitIn' | 'dissolveIn' | 'wheelIn' | 'blindsIn' | 'boxIn' | 'floatIn' | 'riseUp' | 'swivel' | 'expandIn' | 'checkerboardIn' | 'flashIn' | 'peekIn' | 'randomBarsIn' | 'spinnerIn' | 'growTurnIn' | 'fadeOut' | 'flyOut' | 'zoomOut' | 'bounceOut' | 'wipeOut' | 'shrinkOut' | 'dissolveOut' | 'disappear' | 'spin' | 'pulse' | 'colorWave' | 'bounce' | 'flash' | 'growShrink' | 'teeter' | 'transparency' | 'boldFlash' | 'wave';
|
|
3799
|
+
/** Animation timing curve. */
|
|
3800
|
+
type PptxAnimationTimingCurve = 'ease' | 'ease-in' | 'ease-out' | 'linear';
|
|
3801
|
+
/** Repeat mode for animations. */
|
|
3802
|
+
type PptxAnimationRepeatMode = 'untilNextClick' | 'untilEndOfSlide';
|
|
3803
|
+
/** Animation trigger type from OOXML `p:cTn`. */
|
|
3804
|
+
type PptxAnimationTrigger = 'onClick' | 'onShapeClick' | 'onHover' | 'afterPrevious' | 'withPrevious' | 'afterDelay';
|
|
3805
|
+
/**
|
|
3806
|
+
* Native animation kind. The historic shape-targeted preset animations are
|
|
3807
|
+
* implicitly the default kind (`undefined`). Media animations (`p:audio`,
|
|
3808
|
+
* `p:video`) emit dedicated entries so playback order on the slide timeline
|
|
3809
|
+
* is preserved alongside other animations.
|
|
3810
|
+
*/
|
|
3811
|
+
type PptxNativeAnimationKind = 'media';
|
|
3812
|
+
/**
|
|
3813
|
+
* Parsed native animation record from `p:timing / p:tnLst`.
|
|
3814
|
+
*
|
|
3815
|
+
* Represents a single animation node in the OOXML timing tree,
|
|
3816
|
+
* including motion paths, scale transforms, and text build settings.
|
|
3817
|
+
*
|
|
3818
|
+
* @example
|
|
3819
|
+
* ```ts
|
|
3820
|
+
* const anim: PptxNativeAnimation = {
|
|
3821
|
+
* targetId: "shape_1",
|
|
3822
|
+
* presetClass: "entr",
|
|
3823
|
+
* presetId: 10,
|
|
3824
|
+
* trigger: "afterPrevious",
|
|
3825
|
+
* durationMs: 500,
|
|
3826
|
+
* };
|
|
3827
|
+
* // => { targetId: "shape_1", presetClass: "entr", presetId: 10, trigger: "afterPrevious", durationMs: 500 }
|
|
3828
|
+
* ```
|
|
3829
|
+
*/
|
|
3830
|
+
interface PptxNativeAnimation {
|
|
3831
|
+
/** Target element/shape ID. */
|
|
3832
|
+
targetId?: string;
|
|
3833
|
+
/** Trigger type. */
|
|
3834
|
+
trigger?: PptxAnimationTrigger;
|
|
3835
|
+
/** Shape ID that triggers this animation when clicked (interactive sequence). */
|
|
3836
|
+
triggerShapeId?: string;
|
|
3837
|
+
/** Effect preset class (entr, exit, emph, path). */
|
|
3838
|
+
presetClass?: 'entr' | 'exit' | 'emph' | 'path';
|
|
3839
|
+
/** Effect preset sub-type identifier. */
|
|
3840
|
+
presetId?: number;
|
|
3841
|
+
/** Duration in milliseconds. */
|
|
3842
|
+
durationMs?: number;
|
|
3843
|
+
/** Delay in milliseconds. */
|
|
3844
|
+
delayMs?: number;
|
|
3845
|
+
/** Trigger delay in milliseconds (for afterDelay). */
|
|
3846
|
+
triggerDelayMs?: number;
|
|
3847
|
+
/** SVG path string for motion path animations (`p:animMotion/@path`). */
|
|
3848
|
+
motionPath?: string;
|
|
3849
|
+
/** Motion origin: "layout" or "parent". */
|
|
3850
|
+
motionOrigin?: string;
|
|
3851
|
+
/** Whether the element auto-rotates to follow the motion path tangent (`p:animMotion/@rAng` = "0"). */
|
|
3852
|
+
motionPathRotateAuto?: boolean;
|
|
3853
|
+
/** Path edit mode from `p:animMotion/@pathEditMode` (e.g. "relative", "fixed"). */
|
|
3854
|
+
motionPathEditMode?: string;
|
|
3855
|
+
/** Comma-separated point-types string from `p:animMotion/@ptsTypes`. */
|
|
3856
|
+
motionPtsTypes?: string;
|
|
3857
|
+
/** Rotation angle in degrees for `p:animRot/@by` (converted from 60000ths). */
|
|
3858
|
+
rotationBy?: number;
|
|
3859
|
+
/** Starting rotation angle in degrees for `p:animRot/@from` (converted from 60000ths). */
|
|
3860
|
+
rotationFrom?: number;
|
|
3861
|
+
/** Ending rotation angle in degrees for `p:animRot/@to` (converted from 60000ths). */
|
|
3862
|
+
rotationTo?: number;
|
|
3863
|
+
/** X scale factor (percentage / 100) for `p:animScale/p:by/@x`. */
|
|
3864
|
+
scaleByX?: number;
|
|
3865
|
+
/** Y scale factor (percentage / 100) for `p:animScale/p:by/@y`. */
|
|
3866
|
+
scaleByY?: number;
|
|
3867
|
+
/** Starting X scale factor for `p:animScale/p:from/@x`. */
|
|
3868
|
+
scaleFromX?: number;
|
|
3869
|
+
/** Starting Y scale factor for `p:animScale/p:from/@y`. */
|
|
3870
|
+
scaleFromY?: number;
|
|
3871
|
+
/** Ending X scale factor for `p:animScale/p:to/@x`. */
|
|
3872
|
+
scaleToX?: number;
|
|
3873
|
+
/** Ending Y scale factor for `p:animScale/p:to/@y`. */
|
|
3874
|
+
scaleToY?: number;
|
|
3875
|
+
/** Whether `p:animScale/@zoomContents` was set ("1"/"true"). */
|
|
3876
|
+
scaleZoomContents?: boolean;
|
|
3877
|
+
/** Parsed `p:tav` keyframes from `p:tavLst` (CT_TLAnimVariantList). */
|
|
3878
|
+
keyframes?: PptxAnimationKeyframe[];
|
|
3879
|
+
/** Repeat count (e.g. `2`, `Infinity` for indefinite). */
|
|
3880
|
+
repeatCount?: number;
|
|
3881
|
+
/** Whether the animation plays in reverse after completion. */
|
|
3882
|
+
autoReverse?: boolean;
|
|
3883
|
+
/** Text build type from `p:bldP/@build` in `p:bldLst`. */
|
|
3884
|
+
buildType?: PptxTextBuildType;
|
|
3885
|
+
/** Build level for multi-level lists from `p:bldP/@bldLvl`. */
|
|
3886
|
+
buildLevel?: number;
|
|
3887
|
+
/** Group ID linking a `p:bldP` entry to its timing animation node. */
|
|
3888
|
+
groupId?: string;
|
|
3889
|
+
/** Sound relationship ID to play when animation triggers (`p:stSnd`). */
|
|
3890
|
+
soundRId?: string;
|
|
3891
|
+
/** Resolved sound file path from relationship. */
|
|
3892
|
+
soundPath?: string;
|
|
3893
|
+
/** Whether to stop any currently playing sound (`p:endSnd`). */
|
|
3894
|
+
stopSound?: boolean;
|
|
3895
|
+
/** Structured start conditions parsed from `p:stCondLst`. */
|
|
3896
|
+
startConditions?: AnimationCondition[];
|
|
3897
|
+
/** Structured end conditions parsed from `p:endCondLst`. */
|
|
3898
|
+
endConditions?: AnimationCondition[];
|
|
3899
|
+
/** Preserved raw `p:endCondLst` XML node for lossless round-trip. */
|
|
3900
|
+
rawEndCondLst?: XmlObject;
|
|
3901
|
+
/** Color animation data from `p:animClr`. */
|
|
3902
|
+
colorAnimation?: PptxColorAnimation;
|
|
3903
|
+
/** Text-level target: character range or paragraph range from `p:txEl`. */
|
|
3904
|
+
textTarget?: PptxTextAnimationTarget;
|
|
3905
|
+
/** Whether this animation is inside an exclusive container (`p:excl`). */
|
|
3906
|
+
exclusive?: boolean;
|
|
3907
|
+
/** Command type from `p:cmd` (@_type: call/evt/verb). */
|
|
3908
|
+
commandType?: string;
|
|
3909
|
+
/** Command string from `p:cmd` (@_cmd). */
|
|
3910
|
+
commandString?: string;
|
|
3911
|
+
/** Iteration configuration from `p:iterate`. */
|
|
3912
|
+
iterate?: PptxAnimationIterate;
|
|
3913
|
+
/**
|
|
3914
|
+
* Discriminator for non-preset animation kinds. When `undefined`, the
|
|
3915
|
+
* entry represents the default shape-effect animation. The `'media'`
|
|
3916
|
+
* kind represents a `p:audio` / `p:video` timing node, captured here so
|
|
3917
|
+
* playback order in the timeline is preserved alongside other animations.
|
|
3918
|
+
*/
|
|
3919
|
+
kind?: PptxNativeAnimationKind;
|
|
3920
|
+
/**
|
|
3921
|
+
* For `kind === 'media'`, identifies whether this is an audio or video
|
|
3922
|
+
* media node so writers know which OOXML element to re-emit.
|
|
3923
|
+
*/
|
|
3924
|
+
mediaType?: 'audio' | 'video';
|
|
3925
|
+
/**
|
|
3926
|
+
* SmartArt build attribute (`p:bldDgm/@bld`) when this animation is
|
|
3927
|
+
* associated with a SmartArt diagram build. Common values include
|
|
3928
|
+
* `whole`, `one`, `lvlOne`, `lvlAtOnce`.
|
|
3929
|
+
*/
|
|
3930
|
+
smartArtBuild?: string;
|
|
3931
|
+
/**
|
|
3932
|
+
* Graphic-frame build attribute (`p:bldGraphic/@bld`) when this animation
|
|
3933
|
+
* is associated with a generic graphic frame build (charts, tables, etc.
|
|
3934
|
+
* that aren't OLE charts).
|
|
3935
|
+
*/
|
|
3936
|
+
graphicBuild?: string;
|
|
3937
|
+
/**
|
|
3938
|
+
* Opaque map of `p:cTn` attributes that don't have a typed home on this
|
|
3939
|
+
* interface but must round-trip through parse → save. Keys are stored
|
|
3940
|
+
* verbatim including the `@_` prefix used by the underlying XML parser
|
|
3941
|
+
* (e.g. `@_evtFilter`, `@_display`, `@_masterRel`, `@_nodePh`,
|
|
3942
|
+
* `@_endSync`, `@_progress`). The `subTnLst` child element is also
|
|
3943
|
+
* preserved here under the literal key `p:subTnLst`. The `afterEffect`
|
|
3944
|
+
* attribute is surfaced separately as a typed boolean ({@link afterEffect})
|
|
3945
|
+
* because it changes write semantics for subsequent timing nodes.
|
|
3946
|
+
*/
|
|
3947
|
+
cTnAttributes?: Record<string, unknown>;
|
|
3948
|
+
/**
|
|
3949
|
+
* Whether the OOXML `p:cTn/@afterEffect` flag is set. Indicates this node
|
|
3950
|
+
* runs after the parent effect's main body has completed; affects how
|
|
3951
|
+
* subsequent peer nodes are sequenced when serialised back to OOXML.
|
|
3952
|
+
*/
|
|
3953
|
+
afterEffect?: boolean;
|
|
3954
|
+
}
|
|
3955
|
+
/**
|
|
3956
|
+
* Single keyframe parsed from a `p:tav` element (CT_TLTimeAnimateValue).
|
|
3957
|
+
*
|
|
3958
|
+
* Each entry in a `p:tavLst` has a time fraction (`@_tm`, in 1000ths of the
|
|
3959
|
+
* total duration; or the literal "indefinite" / "large") and a typed value
|
|
3960
|
+
* child under `p:val/p:strVal|p:boolVal|p:intVal|p:fltVal|p:clrVal`.
|
|
3961
|
+
*
|
|
3962
|
+
* @see ECMA-376 §19.5.30 CT_TLAnimVariantList / §19.5.92 CT_TLTimeAnimateValue
|
|
3963
|
+
*/
|
|
3964
|
+
interface PptxAnimationKeyframe {
|
|
3965
|
+
/**
|
|
3966
|
+
* Time fraction. A finite number is the OOXML `@_tm` integer (0–100000
|
|
3967
|
+
* for percentage, where 100000 = 100% of duration). A string preserves
|
|
3968
|
+
* special tokens ("indefinite", "large").
|
|
3969
|
+
*/
|
|
3970
|
+
tm: number | string;
|
|
3971
|
+
/** Decoded keyframe value. */
|
|
3972
|
+
value: string | boolean | number;
|
|
3973
|
+
/** Discriminant indicating which `p:val` child carried the value. */
|
|
3974
|
+
valueType: 'str' | 'bool' | 'int' | 'flt' | 'clr';
|
|
3975
|
+
/**
|
|
3976
|
+
* Optional formula carried on `p:tav/@_fmla`. Preserved for round-trip
|
|
3977
|
+
* fidelity; consumers may use it to drive computed animation values.
|
|
3978
|
+
*/
|
|
3979
|
+
fmla?: string;
|
|
3980
|
+
}
|
|
3981
|
+
/** Color animation data parsed from `p:animClr`. */
|
|
3982
|
+
interface PptxColorAnimation {
|
|
3983
|
+
/** Color interpolation space: "hsl" or "rgb". */
|
|
3984
|
+
colorSpace: 'hsl' | 'rgb';
|
|
3985
|
+
/** Direction for HSL interpolation: "cw" (clockwise) or "ccw". */
|
|
3986
|
+
direction?: 'cw' | 'ccw';
|
|
3987
|
+
/**
|
|
3988
|
+
* Optional `p:animClr/@path` value preserved for round-trip. When set,
|
|
3989
|
+
* the colour sweep follows a path-based interpolation rather than the
|
|
3990
|
+
* straight cw/ccw arc. ECMA-376 §19.5.13 documents this attribute as a
|
|
3991
|
+
* companion to `@dir` for HSL colour-space animations.
|
|
3992
|
+
*/
|
|
3993
|
+
path?: string;
|
|
3994
|
+
/** Starting color as hex string. */
|
|
3995
|
+
fromColor?: string;
|
|
3996
|
+
/** Ending color as hex string. */
|
|
3997
|
+
toColor?: string;
|
|
3998
|
+
/**
|
|
3999
|
+
* Color delta (for "by" animations) as hex string. For HSL colour-space
|
|
4000
|
+
* animations the value encodes a delta over hue/sat/lum and is preserved
|
|
4001
|
+
* verbatim from the source.
|
|
4002
|
+
*/
|
|
4003
|
+
byColor?: string;
|
|
4004
|
+
/**
|
|
4005
|
+
* Target attribute from `p:attrNameLst` (e.g. "fillcolor", "style.color",
|
|
4006
|
+
* "stroke.color"). Used to determine which CSS property to animate.
|
|
4007
|
+
*/
|
|
4008
|
+
targetAttribute?: string;
|
|
4009
|
+
}
|
|
4010
|
+
/** Text-level animation target from `p:txEl`. */
|
|
4011
|
+
interface PptxTextAnimationTarget {
|
|
4012
|
+
/** Target type: character range or paragraph range. */
|
|
4013
|
+
type: 'charRg' | 'pRg';
|
|
4014
|
+
/** Start index (0-based). */
|
|
4015
|
+
start: number;
|
|
4016
|
+
/** End index (exclusive). */
|
|
4017
|
+
end: number;
|
|
4018
|
+
}
|
|
4019
|
+
/**
|
|
4020
|
+
* Event types for animation conditions from `p:cond/@evt`.
|
|
4021
|
+
*
|
|
4022
|
+
* These map directly to OOXML condition event attribute values
|
|
4023
|
+
* (ISO/IEC 29500-1 S19.5.28 CT_TLTimeCondition).
|
|
4024
|
+
*/
|
|
4025
|
+
type AnimationConditionEvent = 'onBegin' | 'onEnd' | 'begin' | 'end' | 'onClick' | 'onMouseOver' | 'onMouseOut' | 'onNext' | 'onPrev' | 'onStopAudio';
|
|
4026
|
+
/**
|
|
4027
|
+
* Structured representation of a single OOXML animation condition
|
|
4028
|
+
* from `p:cond` elements inside `p:stCondLst` or `p:endCondLst`.
|
|
4029
|
+
*
|
|
4030
|
+
* Conditions control when an animation starts or ends, and can reference
|
|
4031
|
+
* events, time delays, and target time node IDs.
|
|
4032
|
+
*
|
|
4033
|
+
* @example
|
|
4034
|
+
* ```ts
|
|
4035
|
+
* const cond: AnimationCondition = {
|
|
4036
|
+
* event: "onClick",
|
|
4037
|
+
* delay: 0,
|
|
4038
|
+
* targetShapeId: "shape_5",
|
|
4039
|
+
* };
|
|
4040
|
+
* ```
|
|
4041
|
+
*/
|
|
4042
|
+
interface AnimationCondition {
|
|
4043
|
+
/** Event that triggers the condition. */
|
|
4044
|
+
event?: AnimationConditionEvent;
|
|
4045
|
+
/** Delay in milliseconds (from `@_delay`). "indefinite" is represented as -1. */
|
|
4046
|
+
delay?: number;
|
|
4047
|
+
/** Target time node ID reference (from `@_tn`). */
|
|
4048
|
+
targetTimeNodeId?: number;
|
|
4049
|
+
/** Target shape ID from `p:tgtEl/p:spTgt/@spid`. */
|
|
4050
|
+
targetShapeId?: string;
|
|
4051
|
+
/** Whether the condition targets a slide (from `p:tgtEl/p:sldTgt`). */
|
|
4052
|
+
targetSlide?: boolean;
|
|
4053
|
+
}
|
|
4054
|
+
/** Iteration configuration from `p:iterate`. */
|
|
4055
|
+
interface PptxAnimationIterate {
|
|
4056
|
+
/** Iteration type: el (element), lt (letter), wd (word). */
|
|
4057
|
+
type: 'el' | 'lt' | 'wd';
|
|
4058
|
+
/** Whether to iterate backwards. */
|
|
4059
|
+
backwards?: boolean;
|
|
4060
|
+
/** Timing interval (percentage of total duration, in 1000ths). */
|
|
4061
|
+
tmPct?: number;
|
|
4062
|
+
/** Absolute timing interval in ms. */
|
|
4063
|
+
tmAbs?: number;
|
|
4064
|
+
}
|
|
4065
|
+
/** Build type for text build (paragraph/word/letter) animations from `p:bldP/@build`. */
|
|
4066
|
+
type PptxTextBuildType = 'allAtOnce' | 'byParagraph' | 'byWord' | 'byChar';
|
|
4067
|
+
/** Direction for fly-in / fly-out / wipe effects. */
|
|
4068
|
+
type PptxAnimationDirection = 'fromLeft' | 'fromRight' | 'fromTop' | 'fromBottom' | 'fromTopLeft' | 'fromTopRight' | 'fromBottomLeft' | 'fromBottomRight';
|
|
4069
|
+
/** Sequence mode for paragraph-level animations. */
|
|
4070
|
+
type PptxAnimationSequence = 'asOne' | 'byParagraph' | 'byWord' | 'byLetter';
|
|
4071
|
+
/** Behavior after animation finishes. */
|
|
4072
|
+
type PptxAfterAnimationAction = 'none' | 'hideOnNextClick' | 'hideAfterAnimation' | 'dimToColor';
|
|
4073
|
+
/**
|
|
4074
|
+
* High-level animation data associated with a slide element.
|
|
4075
|
+
*
|
|
4076
|
+
* Combines entrance, exit, and emphasis presets with timing and
|
|
4077
|
+
* trigger configuration. Used by the editor’s animation panel
|
|
4078
|
+
* and the `setPptxElementAnimation` tool.
|
|
4079
|
+
*
|
|
4080
|
+
* @example
|
|
4081
|
+
* ```ts
|
|
4082
|
+
* const anim: PptxElementAnimation = {
|
|
4083
|
+
* elementId: "title_1",
|
|
4084
|
+
* entrance: "fadeIn",
|
|
4085
|
+
* durationMs: 600,
|
|
4086
|
+
* order: 1,
|
|
4087
|
+
* trigger: "afterPrevious",
|
|
4088
|
+
* };
|
|
4089
|
+
* // => { elementId: "title_1", entrance: "fadeIn", durationMs: 600, order: 1, trigger: "afterPrevious" }
|
|
4090
|
+
* ```
|
|
4091
|
+
*/
|
|
4092
|
+
interface PptxElementAnimation {
|
|
4093
|
+
elementId: string;
|
|
4094
|
+
entrance?: PptxAnimationPreset;
|
|
4095
|
+
exit?: PptxAnimationPreset;
|
|
4096
|
+
emphasis?: PptxAnimationPreset;
|
|
4097
|
+
durationMs?: number;
|
|
4098
|
+
delayMs?: number;
|
|
4099
|
+
order?: number;
|
|
4100
|
+
trigger?: PptxAnimationTrigger;
|
|
4101
|
+
/** Shape ID that triggers this animation when clicked (interactive sequence). */
|
|
4102
|
+
triggerShapeId?: string;
|
|
4103
|
+
timingCurve?: PptxAnimationTimingCurve;
|
|
4104
|
+
repeatCount?: number;
|
|
4105
|
+
repeatMode?: PptxAnimationRepeatMode;
|
|
4106
|
+
/** Direction for directional effects (fly in/out, wipe, etc.). */
|
|
4107
|
+
direction?: PptxAnimationDirection;
|
|
4108
|
+
/** Sequence mode — animate as one object or by paragraph/word/letter. */
|
|
4109
|
+
sequence?: PptxAnimationSequence;
|
|
4110
|
+
/** What happens after the animation finishes playing. */
|
|
4111
|
+
afterAnimation?: PptxAfterAnimationAction;
|
|
4112
|
+
/** Dim-to color hex (used when afterAnimation is "dimToColor"). */
|
|
4113
|
+
afterAnimationColor?: string;
|
|
4114
|
+
/** SVG motion path string for custom motion path animations. */
|
|
4115
|
+
motionPath?: string;
|
|
4116
|
+
/**
|
|
4117
|
+
* Path edit mode for `p:animMotion/@pathEditMode`. Defaults to "relative"
|
|
4118
|
+
* when emitted without an explicit value.
|
|
4119
|
+
*/
|
|
4120
|
+
motionPathEditMode?: string;
|
|
4121
|
+
/** Comma-separated point-types string for `p:animMotion/@ptsTypes`. */
|
|
4122
|
+
motionPtsTypes?: string;
|
|
4123
|
+
/** Sound relationship ID to play when animation triggers (`p:stSnd`). */
|
|
4124
|
+
soundRId?: string;
|
|
4125
|
+
/** Resolved sound file path from relationship. */
|
|
4126
|
+
soundPath?: string;
|
|
4127
|
+
/** Whether to stop any currently playing sound (`p:endSnd`). */
|
|
4128
|
+
stopSound?: boolean;
|
|
4129
|
+
}
|
|
4130
|
+
|
|
4131
|
+
/**
|
|
4132
|
+
* Metadata types: slide comments, compatibility warnings, tags,
|
|
4133
|
+
* custom properties, core/app document properties.
|
|
4134
|
+
*
|
|
4135
|
+
* @module pptx-types/metadata
|
|
4136
|
+
*/
|
|
4137
|
+
/**
|
|
4138
|
+
* A slide comment — may be a legacy positional comment or a modern
|
|
4139
|
+
* threaded comment with replies.
|
|
4140
|
+
*
|
|
4141
|
+
* @example
|
|
4142
|
+
* ```ts
|
|
4143
|
+
* const comment: PptxComment = {
|
|
4144
|
+
* id: "c1",
|
|
4145
|
+
* text: "Please update this chart.",
|
|
4146
|
+
* author: "Alice",
|
|
4147
|
+
* createdAt: "2024-06-01T10:00:00Z",
|
|
4148
|
+
* resolved: false,
|
|
4149
|
+
* };
|
|
4150
|
+
* // => satisfies PptxComment
|
|
4151
|
+
* ```
|
|
4152
|
+
*/
|
|
4153
|
+
interface PptxComment {
|
|
4154
|
+
id: string;
|
|
4155
|
+
text: string;
|
|
4156
|
+
/** Optional parent comment id for reply threading metadata. */
|
|
4157
|
+
parentId?: string;
|
|
4158
|
+
author?: string;
|
|
4159
|
+
createdAt?: string;
|
|
4160
|
+
x?: number;
|
|
4161
|
+
y?: number;
|
|
4162
|
+
/** Whether this comment has been resolved/marked done. */
|
|
4163
|
+
resolved?: boolean;
|
|
4164
|
+
/** Modern threaded comment support (p15:threadingInfo). */
|
|
4165
|
+
threadId?: string;
|
|
4166
|
+
/** Replies to this comment (for modern threaded comments). */
|
|
4167
|
+
replies?: PptxComment[];
|
|
4168
|
+
/** ID of the element this comment is associated with (if any). */
|
|
4169
|
+
elementId?: string;
|
|
4170
|
+
}
|
|
4171
|
+
/**
|
|
4172
|
+
* A compatibility warning generated during parse or save when the
|
|
4173
|
+
* file uses features not fully supported by the editor.
|
|
4174
|
+
*
|
|
4175
|
+
* @example
|
|
4176
|
+
* ```ts
|
|
4177
|
+
* const warning: PptxCompatibilityWarning = {
|
|
4178
|
+
* code: "UNSUPPORTED_3D",
|
|
4179
|
+
* message: "3D rotation effects may not render accurately.",
|
|
4180
|
+
* severity: "warning",
|
|
4181
|
+
* scope: "element",
|
|
4182
|
+
* slideId: "slide-1",
|
|
4183
|
+
* elementId: "elem-42",
|
|
4184
|
+
* };
|
|
4185
|
+
* // => satisfies PptxCompatibilityWarning
|
|
4186
|
+
* ```
|
|
4187
|
+
*/
|
|
4188
|
+
interface PptxCompatibilityWarning {
|
|
4189
|
+
code: string;
|
|
4190
|
+
message: string;
|
|
4191
|
+
severity: 'info' | 'warning';
|
|
4192
|
+
scope: 'presentation' | 'slide' | 'element' | 'save';
|
|
4193
|
+
slideId?: string;
|
|
4194
|
+
elementId?: string;
|
|
4195
|
+
xmlPath?: string;
|
|
4196
|
+
}
|
|
4197
|
+
|
|
4198
|
+
/**
|
|
4199
|
+
* Slide transition types and the {@link PptxSlideTransition} data structure.
|
|
4200
|
+
*
|
|
4201
|
+
* Represents the `<p:transition>` element on each slide, including
|
|
4202
|
+
* transition type, duration, direction, and advance timing.
|
|
4203
|
+
*
|
|
4204
|
+
* @module pptx-types/transition
|
|
4205
|
+
*/
|
|
4206
|
+
|
|
4207
|
+
/**
|
|
4208
|
+
* Available slide transition effects.
|
|
4209
|
+
*
|
|
4210
|
+
* Maps to the OOXML child element names under `<p:transition>` / `<p14:transition>`.
|
|
4211
|
+
*
|
|
4212
|
+
* @example
|
|
4213
|
+
* ```ts
|
|
4214
|
+
* const t: PptxTransitionType = "morph";
|
|
4215
|
+
* // => "morph" — one of 40+ transition effects
|
|
4216
|
+
* ```
|
|
4217
|
+
*/
|
|
4218
|
+
type PptxTransitionType = 'none' | 'cut' | 'fade' | 'push' | 'wipe' | 'split' | 'randomBar' | 'blinds' | 'checker' | 'circle' | 'comb' | 'cover' | 'diamond' | 'dissolve' | 'plus' | 'pull' | 'random' | 'strips' | 'uncover' | 'wedge' | 'wheel' | 'zoom' | 'newsflash' | 'morph' | 'conveyor' | 'doors' | 'ferris' | 'flash' | 'flythrough' | 'gallery' | 'glitter' | 'honeycomb' | 'pan' | 'prism' | 'reveal' | 'ripple' | 'shred' | 'switch' | 'vortex' | 'warp' | 'wheelReverse' | 'window' | 'cube' | 'flip' | 'rotate' | 'orbit';
|
|
4219
|
+
/** Split orientation from OOXML `@_orient`. */
|
|
4220
|
+
type PptxSplitOrientation = 'horz' | 'vert';
|
|
4221
|
+
/**
|
|
4222
|
+
* Slide transition configuration.
|
|
4223
|
+
*
|
|
4224
|
+
* @example
|
|
4225
|
+
* ```ts
|
|
4226
|
+
* const transition: PptxSlideTransition = {
|
|
4227
|
+
* type: "fade",
|
|
4228
|
+
* durationMs: 700,
|
|
4229
|
+
* advanceOnClick: true,
|
|
4230
|
+
* advanceAfterMs: 5000,
|
|
4231
|
+
* };
|
|
4232
|
+
* // => { type: "fade", durationMs: 700, advanceOnClick: true, advanceAfterMs: 5000 }
|
|
4233
|
+
* ```
|
|
4234
|
+
*/
|
|
4235
|
+
interface PptxSlideTransition {
|
|
4236
|
+
type: PptxTransitionType;
|
|
4237
|
+
durationMs?: number;
|
|
4238
|
+
direction?: string;
|
|
4239
|
+
advanceOnClick?: boolean;
|
|
4240
|
+
advanceAfterMs?: number;
|
|
4241
|
+
/** Number of spokes for wheel transition (1-8). */
|
|
4242
|
+
spokes?: number;
|
|
4243
|
+
/** Pattern type for shred transition. */
|
|
4244
|
+
pattern?: string;
|
|
4245
|
+
/** Through-black flag for blinds/checker (OOXML `@_thruBlk`). */
|
|
4246
|
+
thruBlk?: boolean;
|
|
4247
|
+
/** Split orientation (horz/vert) parsed from `@_orient`. */
|
|
4248
|
+
orient?: PptxSplitOrientation;
|
|
4249
|
+
/** Relationship ID of transition sound from `p:sndAc/p:stSnd/@r:embed` when present. */
|
|
4250
|
+
soundRId?: string;
|
|
4251
|
+
/** Resolved transition sound media path within the package. */
|
|
4252
|
+
soundPath?: string;
|
|
4253
|
+
/** Human-readable sound file name (extracted from soundPath). */
|
|
4254
|
+
soundFileName?: string;
|
|
4255
|
+
/**
|
|
4256
|
+
* When true, the transition stops the currently-playing sound (OOXML `p:sndAc/p:endSnd`).
|
|
4257
|
+
* Mutually exclusive with `soundRId`/`soundPath` (which use `p:stSnd`).
|
|
4258
|
+
*/
|
|
4259
|
+
stopSound?: boolean;
|
|
4260
|
+
/** Preserved sound-action XML node from `p:sndAc` for lossless round-trip. */
|
|
4261
|
+
rawSoundAction?: XmlObject;
|
|
4262
|
+
/** Preserved extension-list XML node from `p:extLst` within the transition for lossless round-trip. */
|
|
4263
|
+
rawExtLst?: XmlObject;
|
|
4264
|
+
}
|
|
4265
|
+
|
|
4266
|
+
/**
|
|
4267
|
+
* A customer data reference from `p:custDataLst / p:custData`.
|
|
4268
|
+
*
|
|
4269
|
+
* Enterprise add-ins and integrations store custom data parts in the
|
|
4270
|
+
* package and reference them via relationship IDs in the slide or
|
|
4271
|
+
* presentation XML.
|
|
4272
|
+
*
|
|
4273
|
+
* @see ECMA-376 Part 1, §19.2.1.3 (custDataLst), §19.3.1.6 (custData)
|
|
4274
|
+
*/
|
|
4275
|
+
interface PptxCustomerData {
|
|
4276
|
+
/** Resolved part path inside the package (e.g. `ppt/customerData/item1.xml`). */
|
|
4277
|
+
id: string;
|
|
4278
|
+
/** Relationship ID referencing the custom data part. */
|
|
4279
|
+
relId: string;
|
|
4280
|
+
/** Raw string content of the custom data part (if resolvable). */
|
|
4281
|
+
data?: string;
|
|
4282
|
+
}
|
|
4283
|
+
/**
|
|
4284
|
+
* An ActiveX control reference from `p:controls / p:control`.
|
|
4285
|
+
*
|
|
4286
|
+
* ActiveX form controls (buttons, text boxes, check boxes, combo boxes, etc.)
|
|
4287
|
+
* are embedded via OLE parts and referenced by relationship ID in the slide XML.
|
|
4288
|
+
*
|
|
4289
|
+
* @see ECMA-376 Part 1, §19.3.1.3 (controls), §19.3.1.2 (control)
|
|
4290
|
+
*/
|
|
4291
|
+
interface PptxActiveXControl {
|
|
4292
|
+
/** Relationship ID referencing the ActiveX binary part. */
|
|
4293
|
+
relId: string;
|
|
4294
|
+
/** Control name from @name attribute. */
|
|
4295
|
+
name?: string;
|
|
4296
|
+
/** Shape ID this control is linked to (from @spid). */
|
|
4297
|
+
shapeId?: string;
|
|
4298
|
+
/** Raw XML for round-trip preservation. */
|
|
4299
|
+
rawXml?: XmlObject;
|
|
4300
|
+
}
|
|
4301
|
+
/**
|
|
4302
|
+
* Pattern fill on a slide background.
|
|
4303
|
+
*
|
|
4304
|
+
* Mirrors the `<a:pattFill>` choice inside `<p:bgPr>`. Renderers should
|
|
4305
|
+
* draw a 2-colour preset pattern (e.g. `dkDnDiag`, `pct50`).
|
|
4306
|
+
*
|
|
4307
|
+
* ECMA-376 §20.1.8.47.
|
|
4308
|
+
*
|
|
4309
|
+
* @example
|
|
4310
|
+
* ```ts
|
|
4311
|
+
* const pattern: PptxSlideBackgroundPattern = {
|
|
4312
|
+
* preset: "ltDnDiag",
|
|
4313
|
+
* fgColor: "#4472C4",
|
|
4314
|
+
* bgColor: "#FFFFFF",
|
|
4315
|
+
* };
|
|
4316
|
+
* // => satisfies PptxSlideBackgroundPattern
|
|
4317
|
+
* ```
|
|
4318
|
+
*/
|
|
4319
|
+
interface PptxSlideBackgroundPattern {
|
|
4320
|
+
/** DrawingML preset pattern token (`@_prst`). */
|
|
4321
|
+
preset: string;
|
|
4322
|
+
/** Foreground colour resolved to `#RRGGBB`. */
|
|
4323
|
+
fgColor?: string;
|
|
4324
|
+
/** Background colour resolved to `#RRGGBB`. */
|
|
4325
|
+
bgColor?: string;
|
|
4326
|
+
}
|
|
4327
|
+
/**
|
|
4328
|
+
* A single slide in a parsed PPTX presentation.
|
|
4329
|
+
*
|
|
4330
|
+
* Contains the element tree, background settings, notes, comments,
|
|
4331
|
+
* transition / animation data, and metadata like layout path and section.
|
|
4332
|
+
*
|
|
4333
|
+
* @example
|
|
4334
|
+
* ```ts
|
|
4335
|
+
* const slide: PptxSlide = {
|
|
4336
|
+
* id: "slide1",
|
|
4337
|
+
* rId: "rId2",
|
|
4338
|
+
* slideNumber: 1,
|
|
4339
|
+
* elements: [titleTextBox, subtitleTextBox],
|
|
4340
|
+
* backgroundColor: "#FFFFFF",
|
|
4341
|
+
* notes: "Remember to mention quarterly goals.",
|
|
4342
|
+
* };
|
|
4343
|
+
* // => satisfies PptxSlide
|
|
4344
|
+
* ```
|
|
4345
|
+
*/
|
|
4346
|
+
interface PptxSlide {
|
|
4347
|
+
id: string;
|
|
4348
|
+
rId: string;
|
|
4349
|
+
sourceSlideId?: string;
|
|
4350
|
+
/** Optional author-supplied slide name (set via `SlideBuilder.setName`). */
|
|
4351
|
+
name?: string;
|
|
4352
|
+
layoutPath?: string;
|
|
4353
|
+
layoutName?: string;
|
|
4354
|
+
slideNumber: number;
|
|
4355
|
+
hidden?: boolean;
|
|
4356
|
+
sectionName?: string;
|
|
4357
|
+
sectionId?: string;
|
|
4358
|
+
elements: PptxElement[];
|
|
4359
|
+
backgroundColor?: string;
|
|
4360
|
+
backgroundImage?: string;
|
|
4361
|
+
backgroundGradient?: string;
|
|
4362
|
+
/**
|
|
4363
|
+
* Pattern fill on the slide background (`<a:pattFill>` inside `<p:bgPr>`).
|
|
4364
|
+
*
|
|
4365
|
+
* When present, renderers should draw a real two-colour pattern using
|
|
4366
|
+
* the named DrawingML preset (e.g. `"ltDnDiag"`, `"pct50"`). The flat
|
|
4367
|
+
* `backgroundColor` field is left set to the foreground colour for
|
|
4368
|
+
* fallback rendering paths that don't understand patterns.
|
|
4369
|
+
*
|
|
4370
|
+
* ECMA-376 §20.1.8.47.
|
|
4371
|
+
*/
|
|
4372
|
+
backgroundPattern?: PptxSlideBackgroundPattern;
|
|
4373
|
+
/**
|
|
4374
|
+
* `<p:bgPr/@shadeToTitle>` — boolean flag instructing the renderer to
|
|
4375
|
+
* shade the background toward the title placeholder colour. Captured
|
|
4376
|
+
* for lossless round-trip; the React renderer currently treats it as
|
|
4377
|
+
* a passthrough hint.
|
|
4378
|
+
*
|
|
4379
|
+
* ECMA-376 §19.3.1.2 (CT_BackgroundProperties).
|
|
4380
|
+
*/
|
|
4381
|
+
backgroundShadeToTitle?: boolean;
|
|
4382
|
+
transition?: PptxSlideTransition;
|
|
4383
|
+
animations?: PptxElementAnimation[];
|
|
4384
|
+
/** Native OOXML animation data parsed from `p:timing`. */
|
|
4385
|
+
nativeAnimations?: PptxNativeAnimation[];
|
|
4386
|
+
/** Preserved raw `p:timing` XML for lossless round-trip of native animations. */
|
|
4387
|
+
rawTiming?: XmlObject;
|
|
4388
|
+
notes?: string;
|
|
4389
|
+
/** Rich text segments for the slide notes (preserves formatting). */
|
|
4390
|
+
notesSegments?: TextSegment[];
|
|
4391
|
+
/**
|
|
4392
|
+
* Parsed shapes from the notes slide's `<p:cSld>/<p:spTree>` so the full
|
|
4393
|
+
* notes-page shape tree can be inspected and mutated, not just the body
|
|
4394
|
+
* placeholder text. When undefined, the existing notes XML is left
|
|
4395
|
+
* untouched on save and only `notes` / `notesSegments` are written.
|
|
4396
|
+
*/
|
|
4397
|
+
notesShapes?: PptxElement[];
|
|
4398
|
+
/**
|
|
4399
|
+
* Per-notes-slide colour map override parsed from `<p:notes>/<p:clrMapOvr>`.
|
|
4400
|
+
* Captured for lossless round-trip of the notes-slide's colour scheme.
|
|
4401
|
+
*/
|
|
4402
|
+
notesClrMapOverride?: Record<string, string>;
|
|
4403
|
+
/** Optional `<p:cSld @name>` value of the notes slide, for round-trip. */
|
|
4404
|
+
notesCSldName?: string;
|
|
4405
|
+
comments?: PptxComment[];
|
|
4406
|
+
warnings?: PptxCompatibilityWarning[];
|
|
4407
|
+
rawXml?: XmlObject;
|
|
4408
|
+
/** Per-slide colour map override parsed from `p:clrMapOvr`. */
|
|
4409
|
+
clrMapOverride?: Record<string, string>;
|
|
4410
|
+
/** Whether background animations should play (`p:bg/@showAnimation`). */
|
|
4411
|
+
backgroundShowAnimation?: boolean;
|
|
4412
|
+
/** Whether master slide shapes should be shown on this slide (`p:sld/@showMasterSp`). */
|
|
4413
|
+
showMasterShapes?: boolean;
|
|
4414
|
+
/** Drawing guides parsed from slide extension list. */
|
|
4415
|
+
guides?: PptxDrawingGuide[];
|
|
4416
|
+
/** When explicitly `false`, the slide is unmodified and save can skip re-serialization. */
|
|
4417
|
+
isDirty?: boolean;
|
|
4418
|
+
/** Customer data references from `p:custDataLst` on this slide. */
|
|
4419
|
+
customerData?: PptxCustomerData[];
|
|
4420
|
+
/** ActiveX control references from `p:controls` on this slide. */
|
|
4421
|
+
activeXControls?: PptxActiveXControl[];
|
|
4422
|
+
/** Per-slide header/footer flags from `<p:hf>` (P-H3). */
|
|
4423
|
+
headerFooterFlags?: PptxHeaderFooterFlags;
|
|
4424
|
+
}
|
|
4425
|
+
|
|
4426
|
+
/** Viewer interaction mode: read-only, edit, presentation, or master-view. */
|
|
4427
|
+
type ViewerMode = 'preview' | 'edit' | 'present' | 'master';
|
|
4428
|
+
/**
|
|
4429
|
+
* Framework-agnostic imperative API contract for the PowerPoint viewer.
|
|
4430
|
+
*
|
|
4431
|
+
* Each binding (React `forwardRef` handle, Vue `defineExpose`, Angular public
|
|
4432
|
+
* methods) implements this interface so consumers get a consistent progressive
|
|
4433
|
+
* API regardless of framework.
|
|
4434
|
+
*/
|
|
4435
|
+
interface PowerPointViewerAPI {
|
|
4436
|
+
/** Serialise the current presentation to `.pptx` bytes. */
|
|
4437
|
+
getContent: () => Promise<Uint8Array>;
|
|
4438
|
+
/** Navigate to a specific slide by zero-based index. */
|
|
4439
|
+
goTo: (slideIndex: number) => void;
|
|
4440
|
+
/** Navigate to the previous slide. */
|
|
4441
|
+
goPrev: () => void;
|
|
4442
|
+
/** Navigate to the next slide. */
|
|
4443
|
+
goNext: () => void;
|
|
4444
|
+
/** Undo the last editing action. No-op when nothing to undo. */
|
|
4445
|
+
undo: () => void;
|
|
4446
|
+
/** Redo the last undone action. No-op when nothing to redo. */
|
|
4447
|
+
redo: () => void;
|
|
4448
|
+
/** Whether an undo action is available. */
|
|
4449
|
+
canUndo: () => boolean;
|
|
4450
|
+
/** Whether a redo action is available. */
|
|
4451
|
+
canRedo: () => boolean;
|
|
4452
|
+
/** Get the current zoom level (1 = 100%). */
|
|
4453
|
+
getZoom: () => number;
|
|
4454
|
+
/** Set the zoom level (clamped to min/max bounds). */
|
|
4455
|
+
setZoom: (level: number) => void;
|
|
4456
|
+
/** Zoom in by one step. */
|
|
4457
|
+
zoomIn: () => void;
|
|
4458
|
+
/** Zoom out by one step. */
|
|
4459
|
+
zoomOut: () => void;
|
|
4460
|
+
/** Reset zoom to 100%. */
|
|
4461
|
+
zoomReset: () => void;
|
|
4462
|
+
/** Get the current viewer mode. */
|
|
4463
|
+
getMode: () => ViewerMode;
|
|
4464
|
+
/** Switch the viewer mode (e.g. 'edit', 'preview', 'present'). */
|
|
4465
|
+
setMode: (mode: ViewerMode) => void;
|
|
4466
|
+
/** Get the zero-based active slide index. */
|
|
4467
|
+
getActiveSlideIndex: () => number;
|
|
4468
|
+
/** Set the active slide by zero-based index (alias of goTo). */
|
|
4469
|
+
setActiveSlideIndex: (index: number) => void;
|
|
4470
|
+
/** Get the total number of slides. */
|
|
4471
|
+
getSlideCount: () => number;
|
|
4472
|
+
/** Whether the document has unsaved changes. */
|
|
4473
|
+
isDirty: () => boolean;
|
|
4474
|
+
/**
|
|
4475
|
+
* Get the full slide array. Returns the actual `PptxSlide[]` from the
|
|
4476
|
+
* internal model with full type information (elements, notes, transitions,
|
|
4477
|
+
* animations, etc.). The returned reference is a snapshot; mutations are
|
|
4478
|
+
* not reflected back unless done via the manipulation methods.
|
|
4479
|
+
*/
|
|
4480
|
+
getSlides: () => readonly PptxSlide[];
|
|
4481
|
+
/** Get a single slide by zero-based index, or undefined if out of range. */
|
|
4482
|
+
getSlide: (index: number) => PptxSlide | undefined;
|
|
4483
|
+
/** Get the currently active slide. */
|
|
4484
|
+
getActiveSlide: () => PptxSlide | undefined;
|
|
4485
|
+
/** Add a blank slide after the given index (or at end if omitted). */
|
|
4486
|
+
addSlide: (afterIndex?: number) => void;
|
|
4487
|
+
/** Delete slides at the given zero-based indexes. At least one slide is kept. */
|
|
4488
|
+
deleteSlides: (indexes: number[]) => void;
|
|
4489
|
+
/** Duplicate slides at the given zero-based indexes. */
|
|
4490
|
+
duplicateSlides: (indexes: number[]) => void;
|
|
4491
|
+
/** Move a slide from one position to another. */
|
|
4492
|
+
moveSlide: (fromIndex: number, toIndex: number) => void;
|
|
4493
|
+
/** Toggle the hidden flag on slides at the given indexes. */
|
|
4494
|
+
toggleHideSlides: (indexes: number[]) => void;
|
|
4495
|
+
/**
|
|
4496
|
+
* Get the elements on a slide. Defaults to the active slide when
|
|
4497
|
+
* `slideIndex` is omitted. Returns the full `PptxElement[]` with
|
|
4498
|
+
* all type-specific properties intact.
|
|
4499
|
+
*/
|
|
4500
|
+
getElements: (slideIndex?: number) => readonly PptxElement[];
|
|
4501
|
+
/** Get a single element by ID from the active slide (or a specified slide). */
|
|
4502
|
+
getElementById: (elementId: string, slideIndex?: number) => PptxElement | undefined;
|
|
4503
|
+
/**
|
|
4504
|
+
* Update one or more properties of an element by ID on the active slide.
|
|
4505
|
+
* Accepts a `Partial<PptxElement>` patch (e.g. `{ x: 100, width: 300 }`).
|
|
4506
|
+
*/
|
|
4507
|
+
updateElement: (elementId: string, updates: Partial<PptxElement>) => void;
|
|
4508
|
+
/** Delete elements by their IDs from the active slide. */
|
|
4509
|
+
deleteElements: (elementIds: string[]) => void;
|
|
4510
|
+
/**
|
|
4511
|
+
* Duplicate an element on the active slide.
|
|
4512
|
+
* Returns the new element's ID, or undefined if the source was not found.
|
|
4513
|
+
*/
|
|
4514
|
+
duplicateElement: (elementId: string) => string | undefined;
|
|
4515
|
+
/** Get the IDs of currently selected elements. */
|
|
4516
|
+
getSelectedElementIds: () => string[];
|
|
4517
|
+
/** Programmatically select elements by their IDs. */
|
|
4518
|
+
selectElements: (ids: string[]) => void;
|
|
4519
|
+
/** Clear the current selection. */
|
|
4520
|
+
clearSelection: () => void;
|
|
4521
|
+
}
|
|
4522
|
+
/** Collaboration role within a session. */
|
|
4523
|
+
type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
|
|
4524
|
+
/**
|
|
4525
|
+
* Collaboration transport.
|
|
4526
|
+
*
|
|
4527
|
+
* - `'websocket'` (default): y-websocket against `serverUrl`.
|
|
4528
|
+
* - `'webrtc'`: y-webrtc peer-to-peer; needs no document server. Peers meet
|
|
4529
|
+
* through the `signaling` servers (WebRTC signaling only, no document data)
|
|
4530
|
+
* and same-browser tabs additionally sync via BroadcastChannel even without
|
|
4531
|
+
* any signaling server, which makes this mode usable from static hosting.
|
|
4532
|
+
*/
|
|
4533
|
+
type CollaborationTransport = 'websocket' | 'webrtc';
|
|
4534
|
+
/**
|
|
4535
|
+
* Real-time collaboration configuration.
|
|
4536
|
+
*
|
|
4537
|
+
* The same shape is accepted by the React, Vue, and Angular bindings.
|
|
4538
|
+
*/
|
|
4539
|
+
interface CollaborationConfig {
|
|
4540
|
+
/** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
|
|
4541
|
+
roomId: string;
|
|
4542
|
+
/**
|
|
4543
|
+
* WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com").
|
|
4544
|
+
* Ignored (may be empty) when `transport` is `'webrtc'`.
|
|
4545
|
+
*/
|
|
4546
|
+
serverUrl: string;
|
|
4547
|
+
/** Transport to use. Defaults to `'websocket'`. */
|
|
4548
|
+
transport?: CollaborationTransport;
|
|
4549
|
+
/**
|
|
4550
|
+
* WebRTC signaling server URLs (only used when `transport` is `'webrtc'`).
|
|
4551
|
+
* Defaults to y-webrtc's built-in public signaling list. Same-browser tabs
|
|
4552
|
+
* sync via BroadcastChannel regardless of signaling availability.
|
|
4553
|
+
*/
|
|
4554
|
+
signaling?: string[];
|
|
4555
|
+
/** Display name for the local user. */
|
|
4556
|
+
userName: string;
|
|
4557
|
+
/** Avatar URL for the local user (optional). */
|
|
4558
|
+
userAvatar?: string;
|
|
4559
|
+
/** Hex colour for the local user's cursor/presence indicator. */
|
|
4560
|
+
userColor?: string;
|
|
4561
|
+
/** Optional authentication token sent with the WebSocket handshake. */
|
|
4562
|
+
authToken?: string;
|
|
4563
|
+
/** Role in the session; defaults to `'collaborator'`. */
|
|
4564
|
+
role?: CollaborationRole;
|
|
4565
|
+
/**
|
|
4566
|
+
* Elected-writer write-back callback (Area 3 of the C3 hardening plan).
|
|
4567
|
+
*
|
|
4568
|
+
* When the local user has `role: 'owner'`, the binding debounces changes and
|
|
4569
|
+
* serializes the current Y.Doc state to a PPTX byte array, then calls this
|
|
4570
|
+
* callback so the host can persist the snapshot. Only one writer (the owner)
|
|
4571
|
+
* does this; other collaborators never trigger write-back, eliminating the
|
|
4572
|
+
* last-save-wins problem.
|
|
4573
|
+
*/
|
|
4574
|
+
onWriteBack?: (bytes: Uint8Array) => void;
|
|
4575
|
+
/**
|
|
4576
|
+
* Debounce delay (ms) between the last Y.Doc change and the write-back
|
|
4577
|
+
* invocation. Defaults to 5000 ms. Set to 0 to write back on every change
|
|
4578
|
+
* (not recommended for large documents).
|
|
4579
|
+
*/
|
|
4580
|
+
writeBackDebounceMs?: number;
|
|
4581
|
+
}
|
|
4582
|
+
/**
|
|
4583
|
+
* A font supplied by the host application. The package never ships fonts:
|
|
4584
|
+
* applications provide a licensed URL, data URL, or blob URL for their users.
|
|
4585
|
+
*/
|
|
4586
|
+
interface ViewerFontSource {
|
|
4587
|
+
family: string;
|
|
4588
|
+
src: string;
|
|
4589
|
+
format?: 'truetype' | 'opentype' | 'woff' | 'woff2';
|
|
4590
|
+
weight?: string | number;
|
|
4591
|
+
style?: 'normal' | 'italic';
|
|
4592
|
+
}
|
|
4593
|
+
|
|
4594
|
+
//#endregion
|
|
4595
|
+
//#region src/theme/context.d.ts
|
|
9
4596
|
interface ViewerThemeProviderProps {
|
|
10
|
-
|
|
11
|
-
|
|
4597
|
+
theme?: ViewerTheme;
|
|
4598
|
+
children: React.ReactNode;
|
|
12
4599
|
}
|
|
13
4600
|
/**
|
|
14
4601
|
* Provides a `ViewerTheme` to all descendant viewer components.
|
|
@@ -18,13 +4605,168 @@ interface ViewerThemeProviderProps {
|
|
|
18
4605
|
* for advanced use-cases where you want to wrap multiple viewers or
|
|
19
4606
|
* share a theme across a wider subtree.
|
|
20
4607
|
*/
|
|
21
|
-
declare function ViewerThemeProvider({ theme, children }: ViewerThemeProviderProps):
|
|
4608
|
+
declare function ViewerThemeProvider({ theme, children }: ViewerThemeProviderProps): react.JSX.Element;
|
|
22
4609
|
/**
|
|
23
4610
|
* Returns the active `ViewerTheme` (if any) from the nearest
|
|
24
4611
|
* `ViewerThemeProvider`.
|
|
25
4612
|
*/
|
|
26
4613
|
declare function useViewerTheme(): ViewerTheme | undefined;
|
|
4614
|
+
//#endregion
|
|
4615
|
+
//#region src/viewer/types-ui.d.ts
|
|
4616
|
+
/**
|
|
4617
|
+
* Base handle interface for file viewer components.
|
|
4618
|
+
* Defined locally to avoid dependency on external file-viewer plugin packages.
|
|
4619
|
+
* Provides a standard `getContent` method used by the host application to
|
|
4620
|
+
* retrieve the current file content (e.g. for saving).
|
|
4621
|
+
*/
|
|
4622
|
+
interface FileViewerHandle {
|
|
4623
|
+
/** Get the current content of the file (for saving) */
|
|
4624
|
+
getContent: () => Promise<string | Uint8Array>;
|
|
4625
|
+
}
|
|
4626
|
+
interface PowerPointViewerProps {
|
|
4627
|
+
/** PowerPoint content as Uint8Array */
|
|
4628
|
+
content: Uint8Array;
|
|
4629
|
+
/** Licensed fonts supplied by the host application. No fonts are bundled. */
|
|
4630
|
+
fonts?: ViewerFontSource[];
|
|
4631
|
+
/** Original file path, used for autosave recovery */
|
|
4632
|
+
filePath?: string;
|
|
4633
|
+
/**
|
|
4634
|
+
* Display name of the open document, shown in the PowerPoint-style title
|
|
4635
|
+
* bar (e.g. "quarterly-review.pptx"). Falls back to a generic label.
|
|
4636
|
+
*/
|
|
4637
|
+
fileName?: string;
|
|
4638
|
+
/** Callback when content has unsaved changes */
|
|
4639
|
+
onDirtyChange?: (isDirty: boolean) => void;
|
|
4640
|
+
onContentChange?: (content: Uint8Array) => void;
|
|
4641
|
+
/** Callback when active slide changes */
|
|
4642
|
+
onActiveSlideChange?: (slideIndex: number) => void;
|
|
4643
|
+
/** Callback when the viewer mode changes (e.g. edit to present). */
|
|
4644
|
+
onModeChange?: (mode: ViewerMode) => void;
|
|
4645
|
+
/** Callback when the zoom level changes. */
|
|
4646
|
+
onZoomChange?: (zoom: number) => void;
|
|
4647
|
+
/** Callback when element selection changes. */
|
|
4648
|
+
onSelectionChange?: (elementIds: string[]) => void;
|
|
4649
|
+
/** Callback when the total slide count changes (slide added/deleted). */
|
|
4650
|
+
onSlideCountChange?: (count: number) => void;
|
|
4651
|
+
/**
|
|
4652
|
+
* Host override for the File ▸ Open action. When provided, the built-in
|
|
4653
|
+
* native file picker is bypassed and this is invoked instead; the host is
|
|
4654
|
+
* then responsible for supplying a new `content` buffer. When omitted, the
|
|
4655
|
+
* viewer opens its own picker and loads the chosen presentation in place.
|
|
4656
|
+
*/
|
|
4657
|
+
onOpenFile?: () => void;
|
|
4658
|
+
/** Whether editing actions are enabled */
|
|
4659
|
+
canEdit?: boolean;
|
|
4660
|
+
/** Optional class name */
|
|
4661
|
+
className?: string;
|
|
4662
|
+
/**
|
|
4663
|
+
* Display name used as the author for comments and annotations.
|
|
4664
|
+
* Falls back to `collaboration.userName` when collaborating, or `'You'`.
|
|
4665
|
+
*/
|
|
4666
|
+
authorName?: string;
|
|
4667
|
+
/**
|
|
4668
|
+
* Theme configuration for customising the viewer's appearance.
|
|
4669
|
+
*
|
|
4670
|
+
* Accepts partial color overrides, a custom border-radius, and
|
|
4671
|
+
* arbitrary CSS custom properties. Unset values fall back to the
|
|
4672
|
+
* built-in dark theme.
|
|
4673
|
+
*
|
|
4674
|
+
* @example
|
|
4675
|
+
* ```tsx
|
|
4676
|
+
* <PowerPointViewer
|
|
4677
|
+
* content={bytes}
|
|
4678
|
+
* theme={{
|
|
4679
|
+
* colors: { primary: "#6366f1", background: "#0f172a" },
|
|
4680
|
+
* radius: "0.75rem",
|
|
4681
|
+
* }}
|
|
4682
|
+
* />
|
|
4683
|
+
* ```
|
|
4684
|
+
*
|
|
4685
|
+
* @see {@link ViewerTheme} for the full type definition.
|
|
4686
|
+
*/
|
|
4687
|
+
theme?: ViewerTheme;
|
|
4688
|
+
/**
|
|
4689
|
+
* Optional real-time collaboration configuration.
|
|
4690
|
+
*
|
|
4691
|
+
* When provided, the viewer enables collaborative editing with live
|
|
4692
|
+
* cursors, user presence indicators, and CRDT-based state sync via Yjs.
|
|
4693
|
+
* Requires `yjs` and `y-websocket` peer dependencies.
|
|
4694
|
+
*
|
|
4695
|
+
* @example
|
|
4696
|
+
* ```tsx
|
|
4697
|
+
* <PowerPointViewer
|
|
4698
|
+
* content={bytes}
|
|
4699
|
+
* collaboration={{
|
|
4700
|
+
* roomId: "my-room-123",
|
|
4701
|
+
* serverUrl: "wss://collab.example.com",
|
|
4702
|
+
* userName: "Alice",
|
|
4703
|
+
* userColor: "#6366f1",
|
|
4704
|
+
* }}
|
|
4705
|
+
* />
|
|
4706
|
+
* ```
|
|
4707
|
+
*/
|
|
4708
|
+
collaboration?: CollaborationConfig;
|
|
4709
|
+
/**
|
|
4710
|
+
* Callback invoked when the user starts a collaboration session from the
|
|
4711
|
+
* Share dialog. The host app should use this to set the `collaboration`
|
|
4712
|
+
* prop with the returned config.
|
|
4713
|
+
*/
|
|
4714
|
+
onStartCollaboration?: (config: CollaborationConfig) => void;
|
|
4715
|
+
/**
|
|
4716
|
+
* Callback invoked when the user stops a collaboration session from the
|
|
4717
|
+
* Share dialog. The host app should clear the `collaboration` prop.
|
|
4718
|
+
*/
|
|
4719
|
+
onStopCollaboration?: () => void;
|
|
4720
|
+
/**
|
|
4721
|
+
* Default values for the Share dialog fields. The host app should provide
|
|
4722
|
+
* these to control the session name, user display name, and server URL.
|
|
4723
|
+
* If omitted, the Share dialog fields will be empty and require user input.
|
|
4724
|
+
*
|
|
4725
|
+
* @example
|
|
4726
|
+
* ```tsx
|
|
4727
|
+
* <PowerPointViewer
|
|
4728
|
+
* shareDefaults={{
|
|
4729
|
+
* roomId: "session-abc123",
|
|
4730
|
+
* userName: "Alice",
|
|
4731
|
+
* serverUrl: "ws://localhost:1234",
|
|
4732
|
+
* }}
|
|
4733
|
+
* />
|
|
4734
|
+
* ```
|
|
4735
|
+
*/
|
|
4736
|
+
shareDefaults?: {
|
|
4737
|
+
roomId?: string;
|
|
4738
|
+
userName?: string;
|
|
4739
|
+
serverUrl?: string;
|
|
4740
|
+
};
|
|
4741
|
+
/**
|
|
4742
|
+
* Opt in to the experimental Three.js SmartArt renderer. When `true`,
|
|
4743
|
+
* SmartArt diagrams render as extruded 3D blocks on a WebGL canvas instead
|
|
4744
|
+
* of flat SVG. Requires the optional `three` peer dependency; when it is not
|
|
4745
|
+
* installed (or the diagram has no geometry), the viewer transparently falls
|
|
4746
|
+
* back to the SVG `SmartArtRenderer`. Default `false`.
|
|
4747
|
+
*/
|
|
4748
|
+
smartArt3D?: boolean;
|
|
4749
|
+
}
|
|
4750
|
+
interface PowerPointViewerHandle extends FileViewerHandle, PowerPointViewerAPI {
|
|
4751
|
+
getContent: () => Promise<Uint8Array>;
|
|
4752
|
+
}
|
|
4753
|
+
|
|
4754
|
+
//#region src/viewer/utils/animation-effects.d.ts
|
|
4755
|
+
declare function getAnimationInitialStyle(preset: PptxAnimationPreset | undefined, nativeAnimation?: PptxNativeAnimation): react__default.CSSProperties;
|
|
4756
|
+
//#endregion
|
|
4757
|
+
//#region src/viewer/PowerPointViewer.d.ts
|
|
4758
|
+
/**
|
|
4759
|
+
* Root React component for the PowerPoint viewer/editor.
|
|
4760
|
+
*
|
|
4761
|
+
* Accepts binary `.pptx` content and renders a full-featured editor with
|
|
4762
|
+
* slide canvas, toolbar, inspector panels, presentation mode, and more.
|
|
4763
|
+
*
|
|
4764
|
+
* Uses `forwardRef` to expose a `PowerPointViewerHandle` for imperative
|
|
4765
|
+
* access (e.g. serialising the current content for saving).
|
|
4766
|
+
*/
|
|
4767
|
+
declare const PowerPointViewer: react.ForwardRefExoticComponent<PowerPointViewerProps & react.RefAttributes<PowerPointViewerHandle>>;
|
|
27
4768
|
|
|
4769
|
+
//#region src/lib/canvas-export.d.ts
|
|
28
4770
|
/**
|
|
29
4771
|
* A drop-in replacement for `html2canvas(element, options)` that first
|
|
30
4772
|
* resolves any oklch / oklab / lch / lab / color() values in the cloned
|
|
@@ -43,4 +4785,5 @@ declare function useViewerTheme(): ViewerTheme | undefined;
|
|
|
43
4785
|
*/
|
|
44
4786
|
declare function renderToCanvas(element: HTMLElement, options?: Partial<Options>): Promise<HTMLCanvasElement>;
|
|
45
4787
|
|
|
46
|
-
export { ViewerThemeProvider, renderToCanvas, useViewerTheme };
|
|
4788
|
+
export { PowerPointViewer, ViewerThemeProvider, defaultCssVars, defaultRadius, defaultThemeColors, getAnimationInitialStyle, renderToCanvas, themeToCssVars, useViewerTheme, vermilionDarkColors, vermilionDarkTheme, vermilionLightColors, vermilionLightTheme, vermilionRadius };
|
|
4789
|
+
export type { PowerPointViewerAPI, PowerPointViewerHandle, PowerPointViewerProps, ViewerMode, ViewerTheme, ViewerThemeColors };
|