返回 presentation-ai
types.ts
1 /**
2 * Types for DOM-based PPTX export system
3 */
4
5 // Position and dimensions in pixels (relative to slide container)
6 export interface ElementPosition {
7 x: number;
8 y: number;
9 width: number;
10 height: number;
11 /** Original pixel aspect ratio (width/height) for preserving shape integrity in PPT export */
12 aspectRatio?: number;
13 /** Which dimension to preserve when using aspectRatio: 'width' recalculates height, 'height' recalculates width */
14 aspectRatioBase?: "width" | "height";
15 /** Center the resized aspect-ratio box within the original measured bounds */
16 centerAspectRatio?: boolean;
17 }
18
19 // Text styling extracted from DOM
20 interface TextStyles {
21 fontFamily: string;
22 fontSize: number; // in px
23 fontWeight: string | number;
24 color: string; // hex color
25 backgroundColor?: string;
26 textAlign?: "left" | "center" | "right" | "justify";
27 textDecoration?: string;
28 fontStyle?: string;
29 lineHeight?: number;
30 bold?: boolean;
31 italic?: boolean;
32 underline?: boolean;
33 }
34
35 // Border styling
36 interface BorderStyles {
37 width: number;
38 color: string;
39 style: string;
40 radius?: number;
41 }
42
43 // Element types we extract
44 // Element types we extract
45 type ExportElementType =
46 | "text"
47 | "table"
48 | "image"
49 | "decor"
50 | "shape"
51 | "backgroundRect";
52
53 // Base export element
54 interface BaseExportElement {
55 type: ExportElementType;
56 position: ElementPosition;
57 borderStyles?: BorderStyles;
58 backgroundColor?: string;
59 borderRadius?: string;
60 }
61
62 // Text element (simple text block)
63 export interface TextExportElement extends BaseExportElement {
64 type: "text";
65 textContent: string;
66 textStyles: TextStyles;
67 /** Original PlateJS node type (e.g., "h1", "h2", "p", "blockquote") for standard font sizing */
68 nodeType?: string;
69 }
70
71 // Table cell
72 export interface TableCell {
73 text: string;
74 isHeader: boolean;
75 colSpan?: number;
76 rowSpan?: number;
77 backgroundColor?: string;
78 textStyles?: TextStyles;
79 widthRatio?: number; // Deprecated in favor of box
80 box?: {
81 x: number;
82 y: number;
83 width: number;
84 height: number;
85 };
86 }
87
88 // Table row
89 export interface TableRow {
90 cells: TableCell[];
91 }
92
93 // Table element
94 export interface TableExportElement extends BaseExportElement {
95 type: "table";
96 rows: TableRow[];
97 headerRowCount?: number;
98 }
99
100 // Image element (in-editor images, not root image)
101 export interface ImageExportElement extends BaseExportElement {
102 type: "image";
103 url: string;
104 alt?: string;
105 imageSource?: "generate" | "search" | "gif" | "upload";
106 sizing?: "contain" | "cover" | "fill";
107 stockImageProvider?: string;
108 }
109
110 // Decorative element with data-decor attribute
111 export interface DecorExportElement extends BaseExportElement {
112 type: "decor";
113 decorType: string;
114 base64Data?: string;
115 sizing: "contain" | "cover" | "fill";
116 }
117
118 export type NativeShapeType =
119 | "arrow"
120 | "pill"
121 | "parallelogram"
122 | "rect"
123 | "ellipse";
124
125 // Native Shape element (for arrows, pills, parallelograms, and timeline marks)
126 export interface ShapeExportElement extends BaseExportElement {
127 type: "shape";
128 shapeType: NativeShapeType;
129 orientation: "horizontal" | "vertical";
130 fillColor: string;
131 textContent?: string;
132 textColor?: string;
133 }
134
135 // Background rectangle element (for component backgrounds like box-item, cycle-item)
136 export interface BackgroundRectExportElement extends BaseExportElement {
137 type: "backgroundRect";
138 fillColor: string; // Background color (hex)
139 cornerRadius?: number; // In pixels
140 borderColor?: string; // Border color if present
141 borderWidth?: number; // Border width in pixels
142 background?: string; // Full CSS background string for gradient support
143 }
144
145 // Union type for all export elements
146 export type ExportElement =
147 | TextExportElement
148 | TableExportElement
149 | ImageExportElement
150 | DecorExportElement
151 | ShapeExportElement
152 | BackgroundRectExportElement;
153
154 // Scanned slide data
155 export interface ScanResult {
156 slideId: string;
157 width: number; // px
158 height: number; // px
159 /** Untransformed source slide width used for px-to-PPT font conversion */
160 sourceWidth: number;
161 /** Untransformed source slide height */
162 sourceHeight: number;
163 elements: ExportElement[];
164 // Resolved presentation styles
165 styles: PresentationStyles;
166 // Root image data (scanned from DOM)
167 rootImage?: RootImageData;
168 // Background image URL (for "background" layout type)
169 backgroundImageUrl?: string;
170 }
171
172 // Resolved presentation styles from CSS variables
173 export interface PresentationStyles {
174 // Colors
175 primaryColor: string;
176 secondaryColor: string;
177 accentColor: string;
178 backgroundColor: string;
179 textColor: string;
180 headingColor: string;
181 cardBackground: string;
182
183 // Fonts
184 headingFont: string;
185 bodyFont: string;
186
187 cardBorderRadius: string;
188 slideBorderRadius: string;
189 buttonBorderRadius: string;
190
191 // Shadows
192 cardShadow: string;
193 buttonShadow: string;
194 slideShadow: string;
195
196 // Transitions
197 transition: string;
198
199 // Other
200 smartLayoutColor: string;
201
202 // Mask
203 mask?: {
204 clipPath?: string;
205 maskImage?: string;
206 maskSize?: string;
207 maskPosition?: string;
208 maskRepeat?: string;
209 };
210 // Background image URL for slides with background layout
211 backgroundImageUrl?: string;
212 }
213
214 // Root image data
215 export interface RootImageData {
216 url: string; // Either original URL or base64 data URL
217 position: ElementPosition;
218 isBase64?: boolean; // True if url is base64 data (captured image)
219 originalUrl?: string; // Original URL of the image (before capture)
220 imageSource?: "generate" | "search" | "gif" | "upload";
221 stockImageProvider?: string;
222 }
223
223 lines TYPESCRIPT