@canva/design 2.7.6-beta.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +146 -7
- package/index.d.ts +5049 -1
- package/lib/cjs/sdk/design/fake/create.js +27 -0
- package/lib/cjs/sdk/design/fake/fake_design_interaction_client.js +15 -5
- package/lib/cjs/sdk/design/index.js +4 -2
- package/lib/cjs/sdk/design/public.js +8 -0
- package/lib/cjs/sdk/design/test/index.js +12 -14
- package/lib/cjs/sdk/design/version.js +1 -1
- package/lib/esm/sdk/design/fake/create.js +17 -0
- package/lib/esm/sdk/design/fake/fake_design_interaction_client.js +15 -5
- package/lib/esm/sdk/design/index.js +3 -1
- package/lib/esm/sdk/design/public.js +2 -0
- package/lib/esm/sdk/design/test/index.js +6 -1
- package/lib/esm/sdk/design/version.js +1 -1
- package/package.json +11 -11
- package/test/index.d.ts +11 -1
- package/beta.d.ts +0 -5306
- package/lib/cjs/sdk/design/beta.js +0 -51
- package/lib/cjs/sdk/design/fake/create_beta.js +0 -83
- package/lib/cjs/sdk/design/test/beta.js +0 -16
- package/lib/esm/sdk/design/beta.js +0 -11
- package/lib/esm/sdk/design/fake/create_beta.js +0 -73
- package/lib/esm/sdk/design/test/beta.js +0 -6
- package/test/beta.d.ts +0 -11
package/index.d.ts
CHANGED
|
@@ -1 +1,5049 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Adds an audio track to the user's design.
|
|
3
|
+
* @public
|
|
4
|
+
* @param audioTrack - The audio track to add to the user's design.
|
|
5
|
+
*
|
|
6
|
+
* @example Add audio track to design
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { addAudioTrack } from "@canva/design";
|
|
9
|
+
* import type { AudioTrack } from "@canva/design";
|
|
10
|
+
* import type { AudioRef } from "@canva/asset";
|
|
11
|
+
*
|
|
12
|
+
* const exampleAudioRef = "YOUR_AUDIO_REF" as AudioRef;
|
|
13
|
+
*
|
|
14
|
+
* const audioTrack: AudioTrack = {
|
|
15
|
+
* ref: exampleAudioRef
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* await addAudioTrack(audioTrack);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare const addAudioTrack: (audioTrack: AudioTrack) => Promise<void>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @public
|
|
25
|
+
* Add element to responsive documents, which slot things into a text stream
|
|
26
|
+
*
|
|
27
|
+
* @example Insert an image at cursor position
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import { addElementAtCursor } from "@canva/design";
|
|
30
|
+
* import type { ImageElement } from "@canva/design";
|
|
31
|
+
* import type { ImageRef } from "@canva/asset";
|
|
32
|
+
*
|
|
33
|
+
* const exampleImageRef = "YOUR_IMAGE_REF" as ImageRef;
|
|
34
|
+
*
|
|
35
|
+
* const imageElement: ImageElement = {
|
|
36
|
+
* type: 'image',
|
|
37
|
+
* ref: exampleImageRef,
|
|
38
|
+
* altText: { text: 'Product image', decorative: false }
|
|
39
|
+
* };
|
|
40
|
+
*
|
|
41
|
+
* await addElementAtCursor(imageElement);
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example Insert a video at cursor position
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { addElementAtCursor } from "@canva/design";
|
|
47
|
+
* import type { VideoElement } from "@canva/design";
|
|
48
|
+
* import type { VideoRef } from "@canva/asset";
|
|
49
|
+
*
|
|
50
|
+
* const exampleVideoRef = "YOUR_VIDEO_REF" as VideoRef;
|
|
51
|
+
*
|
|
52
|
+
* const videoElement: VideoElement = {
|
|
53
|
+
* type: 'video',
|
|
54
|
+
* ref: exampleVideoRef,
|
|
55
|
+
* altText: { text: 'Product demo', decorative: false }
|
|
56
|
+
* };
|
|
57
|
+
*
|
|
58
|
+
* await addElementAtCursor(videoElement);
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @example Insert embedded content at cursor position
|
|
62
|
+
* ```typescript
|
|
63
|
+
* import { addElementAtCursor } from "@canva/design";
|
|
64
|
+
* import type { EmbedElement } from "@canva/design";
|
|
65
|
+
*
|
|
66
|
+
* const embedElement: EmbedElement = {
|
|
67
|
+
* type: 'embed',
|
|
68
|
+
* url: 'https://www.youtube.com/watch?v=...'
|
|
69
|
+
* };
|
|
70
|
+
*
|
|
71
|
+
* await addElementAtCursor(embedElement);
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @example Insert text at cursor position
|
|
75
|
+
* ```typescript
|
|
76
|
+
* import { addElementAtCursor } from "@canva/design";
|
|
77
|
+
* import type { TextElement } from "@canva/design";
|
|
78
|
+
*
|
|
79
|
+
* const textElement: TextElement = {
|
|
80
|
+
* type: 'text',
|
|
81
|
+
* children: ['Hello World'],
|
|
82
|
+
* fontSize: 24,
|
|
83
|
+
* color: '#000000'
|
|
84
|
+
* };
|
|
85
|
+
*
|
|
86
|
+
* await addElementAtCursor(textElement);
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @example Insert formatted text at cursor position
|
|
90
|
+
* ```typescript
|
|
91
|
+
* import { addElementAtCursor, createRichtextRange } from "@canva/design";
|
|
92
|
+
* import type { RichtextElement } from "@canva/design";
|
|
93
|
+
*
|
|
94
|
+
* const range = createRichtextRange();
|
|
95
|
+
* range.appendText('Rich Text Content', { color: '#000000' });
|
|
96
|
+
*
|
|
97
|
+
* const richtextElement: RichtextElement = {
|
|
98
|
+
* type: 'richtext',
|
|
99
|
+
* range
|
|
100
|
+
* };
|
|
101
|
+
*
|
|
102
|
+
* await addElementAtCursor(richtextElement);
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @example Insert a table at cursor position
|
|
106
|
+
* ```typescript
|
|
107
|
+
* import { addElementAtCursor } from "@canva/design";
|
|
108
|
+
* import type { TableElement } from "@canva/design";
|
|
109
|
+
*
|
|
110
|
+
* const tableElement: TableElement = {
|
|
111
|
+
* type: 'table',
|
|
112
|
+
* rows: [
|
|
113
|
+
* {
|
|
114
|
+
* cells: [
|
|
115
|
+
* { type: 'string', value: 'Header 1' },
|
|
116
|
+
* { type: 'string', value: 'Header 2' }
|
|
117
|
+
* ]
|
|
118
|
+
* },
|
|
119
|
+
* {
|
|
120
|
+
* cells: [
|
|
121
|
+
* { type: 'string', value: 'Data 1' },
|
|
122
|
+
* { type: 'string', value: 'Data 2' }
|
|
123
|
+
* ]
|
|
124
|
+
* }
|
|
125
|
+
* ]
|
|
126
|
+
* };
|
|
127
|
+
*
|
|
128
|
+
* await addElementAtCursor(tableElement);
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export declare const addElementAtCursor: (element: ElementAtCursor) => Promise<void>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @public
|
|
135
|
+
* Add element to fixed designs, which use a coordinate-based positioning system.
|
|
136
|
+
*
|
|
137
|
+
* @example Insert an image at specific coordinates
|
|
138
|
+
* ```typescript
|
|
139
|
+
* import { addElementAtPoint } from "@canva/design";
|
|
140
|
+
* import type { ImageElementAtPoint } from "@canva/design";
|
|
141
|
+
* import type { ImageRef } from "@canva/asset";
|
|
142
|
+
*
|
|
143
|
+
* const exampleImageRef = "YOUR_IMAGE_REF" as ImageRef;
|
|
144
|
+
*
|
|
145
|
+
* const imageElement: ImageElementAtPoint = {
|
|
146
|
+
* type: 'image',
|
|
147
|
+
* ref: exampleImageRef,
|
|
148
|
+
* altText: { text: 'Product image', decorative: false },
|
|
149
|
+
* top: 100,
|
|
150
|
+
* left: 100,
|
|
151
|
+
* width: 300,
|
|
152
|
+
* height: 200
|
|
153
|
+
* };
|
|
154
|
+
*
|
|
155
|
+
* await addElementAtPoint(imageElement);
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @example Insert a video at specific coordinates
|
|
159
|
+
* ```typescript
|
|
160
|
+
* import { addElementAtPoint } from "@canva/design";
|
|
161
|
+
* import type { VideoElementAtPoint } from "@canva/design";
|
|
162
|
+
* import type { VideoRef } from "@canva/asset";
|
|
163
|
+
*
|
|
164
|
+
* const exampleVideoRef = "YOUR_VIDEO_REF" as VideoRef;
|
|
165
|
+
*
|
|
166
|
+
* const videoElement: VideoElementAtPoint = {
|
|
167
|
+
* type: 'video',
|
|
168
|
+
* ref: exampleVideoRef,
|
|
169
|
+
* altText: { text: 'Product demo', decorative: false },
|
|
170
|
+
* top: 100,
|
|
171
|
+
* left: 100,
|
|
172
|
+
* width: 400,
|
|
173
|
+
* height: 300
|
|
174
|
+
* };
|
|
175
|
+
*
|
|
176
|
+
* await addElementAtPoint(videoElement);
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* @example Insert embedded content at specific coordinates
|
|
180
|
+
* ```typescript
|
|
181
|
+
* import { addElementAtPoint } from "@canva/design";
|
|
182
|
+
* import type { EmbedElementAtPoint } from "@canva/design";
|
|
183
|
+
*
|
|
184
|
+
* const embedElement: EmbedElementAtPoint = {
|
|
185
|
+
* type: 'embed',
|
|
186
|
+
* url: 'https://www.youtube.com/watch?v=...',
|
|
187
|
+
* top: 100,
|
|
188
|
+
* left: 100,
|
|
189
|
+
* width: 560,
|
|
190
|
+
* height: 315
|
|
191
|
+
* };
|
|
192
|
+
*
|
|
193
|
+
* await addElementAtPoint(embedElement);
|
|
194
|
+
* ```
|
|
195
|
+
*
|
|
196
|
+
* @example Insert text at specific coordinates
|
|
197
|
+
* ```typescript
|
|
198
|
+
* import { addElementAtPoint } from "@canva/design";
|
|
199
|
+
* import type { TextElementAtPoint } from "@canva/design";
|
|
200
|
+
*
|
|
201
|
+
* const textElement: TextElementAtPoint = {
|
|
202
|
+
* type: 'text',
|
|
203
|
+
* children: ['Hello World'],
|
|
204
|
+
* top: 100,
|
|
205
|
+
* left: 100,
|
|
206
|
+
* width: 200,
|
|
207
|
+
* fontSize: 24,
|
|
208
|
+
* color: '#000000',
|
|
209
|
+
* textAlign: 'justify'
|
|
210
|
+
* };
|
|
211
|
+
*
|
|
212
|
+
* await addElementAtPoint(textElement);
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
export declare const addElementAtPoint: (element: DesignElement | ElementAtPoint) => Promise<void>;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* @deprecated
|
|
219
|
+
* @public
|
|
220
|
+
* Adds a native element to the user's design.
|
|
221
|
+
* @param element - The element to add to the user's design.
|
|
222
|
+
*
|
|
223
|
+
* @example Basic usage
|
|
224
|
+
* ```typescript
|
|
225
|
+
* import { addNativeElement } from "@canva/design";
|
|
226
|
+
* import type { NativeElementWithBox } from "@canva/design";
|
|
227
|
+
*
|
|
228
|
+
* const element: NativeElementWithBox = {
|
|
229
|
+
* type: 'text',
|
|
230
|
+
* children: ['Legacy element'],
|
|
231
|
+
* top: 100,
|
|
232
|
+
* left: 100,
|
|
233
|
+
* width: 200
|
|
234
|
+
* };
|
|
235
|
+
*
|
|
236
|
+
* await addNativeElement(element);
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export declare const addNativeElement: (element: NativeElement | NativeElementWithBox) => Promise<void>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @public
|
|
243
|
+
* Adds a new page immediately after the currently selected page.
|
|
244
|
+
* @param opts - Configuration for the new page to be added.
|
|
245
|
+
*
|
|
246
|
+
* @example Create empty page
|
|
247
|
+
* ```typescript
|
|
248
|
+
* import { addPage } from "@canva/design";
|
|
249
|
+
*
|
|
250
|
+
* await addPage();
|
|
251
|
+
* ```
|
|
252
|
+
*
|
|
253
|
+
* @example Create page with title
|
|
254
|
+
* ```typescript
|
|
255
|
+
* import { addPage } from "@canva/design";
|
|
256
|
+
*
|
|
257
|
+
* await addPage({
|
|
258
|
+
* title: 'My New Page'
|
|
259
|
+
* });
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* @example Create page with background color
|
|
263
|
+
* ```typescript
|
|
264
|
+
* import { addPage } from "@canva/design";
|
|
265
|
+
* import type { PageBackgroundFill } from "@canva/design";
|
|
266
|
+
*
|
|
267
|
+
* const background: PageBackgroundFill = {
|
|
268
|
+
* color: '#F5F5F5',
|
|
269
|
+
* };
|
|
270
|
+
*
|
|
271
|
+
* await addPage({ background });
|
|
272
|
+
* ```
|
|
273
|
+
*
|
|
274
|
+
* @example Create page with background image
|
|
275
|
+
* ```typescript
|
|
276
|
+
* import { addPage } from "@canva/design";
|
|
277
|
+
* import type { PageBackgroundFill } from "@canva/design";
|
|
278
|
+
* import type { ImageRef } from "@canva/asset";
|
|
279
|
+
*
|
|
280
|
+
* const exampleImageRef = "YOUR_IMAGE_REF" as ImageRef;
|
|
281
|
+
*
|
|
282
|
+
* const background: PageBackgroundFill = {
|
|
283
|
+
* asset: {
|
|
284
|
+
* type: 'image',
|
|
285
|
+
* ref: exampleImageRef,
|
|
286
|
+
* altText: { text: 'Background image', decorative: true }
|
|
287
|
+
* },
|
|
288
|
+
* };
|
|
289
|
+
*
|
|
290
|
+
* await addPage({ background });
|
|
291
|
+
* ```
|
|
292
|
+
*
|
|
293
|
+
* @example Create page with multiple elements
|
|
294
|
+
* ```typescript
|
|
295
|
+
* import { addPage } from "@canva/design";
|
|
296
|
+
* import type { TextElementAtPoint, ImageElementAtPoint } from "@canva/design";
|
|
297
|
+
* import type { ImageRef } from "@canva/asset";
|
|
298
|
+
*
|
|
299
|
+
* const exampleImageRef = "YOUR_IMAGE_REF" as ImageRef;
|
|
300
|
+
*
|
|
301
|
+
* await addPage({
|
|
302
|
+
* elements: [
|
|
303
|
+
* {
|
|
304
|
+
* type: 'text',
|
|
305
|
+
* children: ['Page Title'],
|
|
306
|
+
* top: 50,
|
|
307
|
+
* left: 100,
|
|
308
|
+
* width: 400,
|
|
309
|
+
* fontSize: 32,
|
|
310
|
+
* textAlign: 'center'
|
|
311
|
+
* } as TextElementAtPoint,
|
|
312
|
+
* {
|
|
313
|
+
* type: 'text',
|
|
314
|
+
* children: ['Subtitle text'],
|
|
315
|
+
* top: 100,
|
|
316
|
+
* left: 100,
|
|
317
|
+
* width: 400,
|
|
318
|
+
* fontSize: 18,
|
|
319
|
+
* textAlign: 'center'
|
|
320
|
+
* } as TextElementAtPoint,
|
|
321
|
+
* {
|
|
322
|
+
* type: 'image',
|
|
323
|
+
* ref: exampleImageRef,
|
|
324
|
+
* altText: { text: 'Featured image', decorative: false },
|
|
325
|
+
* top: 150,
|
|
326
|
+
* left: 200,
|
|
327
|
+
* width: 200,
|
|
328
|
+
* height: 200
|
|
329
|
+
* } as ImageElementAtPoint,
|
|
330
|
+
* ]
|
|
331
|
+
* });
|
|
332
|
+
* ```
|
|
333
|
+
*
|
|
334
|
+
* @example Create page with custom dimensions
|
|
335
|
+
* ```typescript
|
|
336
|
+
* import { addPage } from "@canva/design";
|
|
337
|
+
*
|
|
338
|
+
* await addPage({
|
|
339
|
+
* dimensions: {
|
|
340
|
+
* width: 300,
|
|
341
|
+
* height: 300,
|
|
342
|
+
* },
|
|
343
|
+
* });
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
export declare const addPage: (opts?: {
|
|
347
|
+
/** Elements to be added to the page. */
|
|
348
|
+
elements?: ElementAtPoint[];
|
|
349
|
+
/** The page background. This can be a solid color, an image or a video. */
|
|
350
|
+
background?: PageBackgroundFill;
|
|
351
|
+
/** A page title which must be no longer than 255 characters */
|
|
352
|
+
title?: string;
|
|
353
|
+
/**
|
|
354
|
+
* The optional custom dimensions in pixels for the new page. The following constraints apply:
|
|
355
|
+
* - `width` and `height` cannot be lower than 40 or higher than 8000
|
|
356
|
+
* - The total area of the new page cannot exceed 25_000_000
|
|
357
|
+
* In case this is not specified, the default dimensions for the design type will be used.
|
|
358
|
+
*/
|
|
359
|
+
dimensions?: {
|
|
360
|
+
width: number;
|
|
361
|
+
height: number;
|
|
362
|
+
};
|
|
363
|
+
}) => Promise<void>;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* @public
|
|
367
|
+
* Alternative text for a11y compliance.
|
|
368
|
+
*/
|
|
369
|
+
export declare type AltText = {
|
|
370
|
+
/**
|
|
371
|
+
* The text content.
|
|
372
|
+
*/
|
|
373
|
+
text: string;
|
|
374
|
+
/**
|
|
375
|
+
* Indicates where the alternative text should be displayed.
|
|
376
|
+
*
|
|
377
|
+
* @remarks
|
|
378
|
+
* - If `true`, the alternative text will only be displayed in the editor.
|
|
379
|
+
* - If `false`, the alternative text will be displayed in the editor and in view-only mode.
|
|
380
|
+
*/
|
|
381
|
+
decorative: boolean | undefined;
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @public
|
|
386
|
+
* A callback that runs when:
|
|
387
|
+
*
|
|
388
|
+
* - the app element is created
|
|
389
|
+
* - the app element's data is updated
|
|
390
|
+
* - the user selects an existing app element
|
|
391
|
+
*
|
|
392
|
+
* @param appElement - Information about the app element that was changed.
|
|
393
|
+
*
|
|
394
|
+
* @example Handle element selection
|
|
395
|
+
* ```typescript
|
|
396
|
+
* import { initAppElement } from "@canva/design";
|
|
397
|
+
*
|
|
398
|
+
* const appElement = initAppElement<{ content: string }>({
|
|
399
|
+
* render: (data) => {
|
|
400
|
+
* // Render based on data
|
|
401
|
+
* return [{
|
|
402
|
+
* type: 'text',
|
|
403
|
+
* children: [data.content || 'Default text'],
|
|
404
|
+
* top: 0,
|
|
405
|
+
* left: 0,
|
|
406
|
+
* width: 200
|
|
407
|
+
* }];
|
|
408
|
+
* }
|
|
409
|
+
* });
|
|
410
|
+
*
|
|
411
|
+
* appElement.registerOnElementChange((element) => {
|
|
412
|
+
* if (element) {
|
|
413
|
+
* // Element selected or created, do something with the `element.data`
|
|
414
|
+
* } else {
|
|
415
|
+
* // No element selected
|
|
416
|
+
* }
|
|
417
|
+
* });
|
|
418
|
+
* ```
|
|
419
|
+
*
|
|
420
|
+
* @example Update element data when selected
|
|
421
|
+
* ```typescript
|
|
422
|
+
* import { initAppElement } from "@canva/design";
|
|
423
|
+
*
|
|
424
|
+
* const appElement = initAppElement<{
|
|
425
|
+
* content: string;
|
|
426
|
+
* lastSelected: number;
|
|
427
|
+
* lastUpdated: number;
|
|
428
|
+
* metadata: { lastEdited: number; editCount: number };
|
|
429
|
+
* }>({
|
|
430
|
+
* render: (data) => {
|
|
431
|
+
* // Render based on data
|
|
432
|
+
* return [{
|
|
433
|
+
* type: 'text',
|
|
434
|
+
* children: [data.content || 'Default text'],
|
|
435
|
+
* top: 0,
|
|
436
|
+
* left: 0,
|
|
437
|
+
* width: 200
|
|
438
|
+
* }];
|
|
439
|
+
* }
|
|
440
|
+
* });
|
|
441
|
+
*
|
|
442
|
+
* appElement.registerOnElementChange(async (element) => {
|
|
443
|
+
* if (element) {
|
|
444
|
+
* // Use the update method to modify the element's data
|
|
445
|
+
* await element.update({
|
|
446
|
+
* data: {
|
|
447
|
+
* ...element.data,
|
|
448
|
+
* lastSelected: Date.now()
|
|
449
|
+
* }
|
|
450
|
+
* });
|
|
451
|
+
* }
|
|
452
|
+
* });
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
export declare type AppElementChangeHandler<A extends AppElementData> = (appElement: {
|
|
456
|
+
/**
|
|
457
|
+
* The app element data in its most recent state.
|
|
458
|
+
*/
|
|
459
|
+
data: A;
|
|
460
|
+
/**
|
|
461
|
+
* The version number of the app.
|
|
462
|
+
*/
|
|
463
|
+
version: number;
|
|
464
|
+
/**
|
|
465
|
+
* Function to update the app element data.
|
|
466
|
+
*
|
|
467
|
+
* @param opts - The data and placement to update the app element with.
|
|
468
|
+
*
|
|
469
|
+
* @example Update element data only
|
|
470
|
+
* ```typescript
|
|
471
|
+
* if (element) {
|
|
472
|
+
* await element.update({
|
|
473
|
+
* data: {
|
|
474
|
+
* ...element.data,
|
|
475
|
+
* content: 'Updated content',
|
|
476
|
+
* lastUpdated: Date.now()
|
|
477
|
+
* }
|
|
478
|
+
* });
|
|
479
|
+
* }
|
|
480
|
+
* ```
|
|
481
|
+
*
|
|
482
|
+
* @example Update data and placement
|
|
483
|
+
* ```typescript
|
|
484
|
+
* if (element) {
|
|
485
|
+
* await element.update({
|
|
486
|
+
* data: {
|
|
487
|
+
* ...element.data,
|
|
488
|
+
* content: 'Positioned element'
|
|
489
|
+
* },
|
|
490
|
+
* placement: {
|
|
491
|
+
* top: 200,
|
|
492
|
+
* left: 200,
|
|
493
|
+
* width: 300,
|
|
494
|
+
* height: 100
|
|
495
|
+
* }
|
|
496
|
+
* });
|
|
497
|
+
* }
|
|
498
|
+
* ```
|
|
499
|
+
*
|
|
500
|
+
* @example Add metadata to element
|
|
501
|
+
* ```typescript
|
|
502
|
+
* if (element) {
|
|
503
|
+
* await element.update({
|
|
504
|
+
* data: {
|
|
505
|
+
* ...element.data,
|
|
506
|
+
* metadata: {
|
|
507
|
+
* ...(element.data.metadata || {}),
|
|
508
|
+
* lastEdited: Date.now(),
|
|
509
|
+
* editCount: (element.data.metadata?.editCount || 0) + 1,
|
|
510
|
+
* },
|
|
511
|
+
* },
|
|
512
|
+
* });
|
|
513
|
+
* }
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
update: (opts: AppElementOptions<A>) => Promise<void>;
|
|
517
|
+
} | undefined) => void;
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* @public
|
|
521
|
+
* A client that provides methods for creating and managing the lifecycle of an app element.
|
|
522
|
+
*/
|
|
523
|
+
export declare interface AppElementClient<A extends AppElementData> {
|
|
524
|
+
/**
|
|
525
|
+
* @deprecated This type has been superseded, use `addElement` or `registerOnElementChange` instead.
|
|
526
|
+
* If an app element is selected, the element's data is overwritten and the element is re-rendered.
|
|
527
|
+
* Otherwise, the provided data is used to create a new app element.
|
|
528
|
+
* @param appElementData - The data to attach to the app element. Existing data will be overwritten.
|
|
529
|
+
* @param placement - The position, dimensions, and rotation of the app element.
|
|
530
|
+
*
|
|
531
|
+
* @example Create or update an element (deprecated)
|
|
532
|
+
* ```typescript
|
|
533
|
+
* import { initAppElement } from "@canva/design";
|
|
534
|
+
*
|
|
535
|
+
* // Initialize the app element client
|
|
536
|
+
* const appElement = initAppElement<{ content: string; timestamp: number }>({
|
|
537
|
+
* render: (data) => {
|
|
538
|
+
* return [{
|
|
539
|
+
* type: 'text',
|
|
540
|
+
* children: [data.content || 'Default text'],
|
|
541
|
+
* top: 100,
|
|
542
|
+
* left: 100,
|
|
543
|
+
* width: 200
|
|
544
|
+
* }];
|
|
545
|
+
* }
|
|
546
|
+
* });
|
|
547
|
+
*
|
|
548
|
+
* // Create a new element or update selected element
|
|
549
|
+
* await appElement.addOrUpdateElement({
|
|
550
|
+
* content: 'Hello from the app',
|
|
551
|
+
* timestamp: Date.now()
|
|
552
|
+
* });
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @example Update with specific placement (deprecated)
|
|
556
|
+
* ```typescript
|
|
557
|
+
* import { initAppElement } from "@canva/design";
|
|
558
|
+
*
|
|
559
|
+
* const appElement = initAppElement<{ content: string }>({
|
|
560
|
+
* render: (data) => {
|
|
561
|
+
* return [{
|
|
562
|
+
* type: 'text',
|
|
563
|
+
* children: [data.content || 'Default text'],
|
|
564
|
+
* top: 0,
|
|
565
|
+
* left: 0,
|
|
566
|
+
* width: 200
|
|
567
|
+
* }];
|
|
568
|
+
* }
|
|
569
|
+
* });
|
|
570
|
+
*
|
|
571
|
+
* // Create or update with specific placement
|
|
572
|
+
* await appElement.addOrUpdateElement(
|
|
573
|
+
* {
|
|
574
|
+
* content: 'Positioned content'
|
|
575
|
+
* },
|
|
576
|
+
* {
|
|
577
|
+
* top: 200,
|
|
578
|
+
* left: 200,
|
|
579
|
+
* width: 300,
|
|
580
|
+
* height: 100
|
|
581
|
+
* }
|
|
582
|
+
* );
|
|
583
|
+
* ```
|
|
584
|
+
*/
|
|
585
|
+
addOrUpdateElement(appElementData: A, placement?: Placement): Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* Adds a new app element to the design.
|
|
588
|
+
* @param opts - The data and placement of the app element.
|
|
589
|
+
*
|
|
590
|
+
* @example Add new element with data
|
|
591
|
+
* ```typescript
|
|
592
|
+
* import { initAppElement } from "@canva/design";
|
|
593
|
+
*
|
|
594
|
+
* const appElement = initAppElement<{ content: string; id: string }>({
|
|
595
|
+
* render: (data) => {
|
|
596
|
+
* return [{
|
|
597
|
+
* type: 'text',
|
|
598
|
+
* children: [data.content || 'Default text'],
|
|
599
|
+
* top: 0,
|
|
600
|
+
* left: 0,
|
|
601
|
+
* width: 200
|
|
602
|
+
* }];
|
|
603
|
+
* }
|
|
604
|
+
* });
|
|
605
|
+
*
|
|
606
|
+
* // Add a new element
|
|
607
|
+
* await appElement.addElement({
|
|
608
|
+
* data: {
|
|
609
|
+
* content: 'New element content',
|
|
610
|
+
* id: 'element-' + Date.now()
|
|
611
|
+
* }
|
|
612
|
+
* });
|
|
613
|
+
* ```
|
|
614
|
+
*
|
|
615
|
+
* @example Add element with specific placement
|
|
616
|
+
* ```typescript
|
|
617
|
+
* import { initAppElement } from "@canva/design";
|
|
618
|
+
*
|
|
619
|
+
* const appElement = initAppElement<{
|
|
620
|
+
* title: string;
|
|
621
|
+
* description: string;
|
|
622
|
+
* createdAt: number;
|
|
623
|
+
* }>({
|
|
624
|
+
* render: (data) => {
|
|
625
|
+
* return [{
|
|
626
|
+
* type: 'text',
|
|
627
|
+
* children: [data.title || 'Default title'],
|
|
628
|
+
* top: 0,
|
|
629
|
+
* left: 0,
|
|
630
|
+
* width: 300,
|
|
631
|
+
* fontWeight: 'bold',
|
|
632
|
+
* fontSize: 24
|
|
633
|
+
* }, {
|
|
634
|
+
* type: 'text',
|
|
635
|
+
* children: [data.description || 'Default description'],
|
|
636
|
+
* top: 50,
|
|
637
|
+
* left: 0,
|
|
638
|
+
* width: 300
|
|
639
|
+
* }];
|
|
640
|
+
* }
|
|
641
|
+
* });
|
|
642
|
+
*
|
|
643
|
+
* // Add element with specific placement
|
|
644
|
+
* await appElement.addElement({
|
|
645
|
+
* data: {
|
|
646
|
+
* title: 'Element Title',
|
|
647
|
+
* description: 'This is a description of the element',
|
|
648
|
+
* createdAt: Date.now()
|
|
649
|
+
* },
|
|
650
|
+
* placement: {
|
|
651
|
+
* top: 100,
|
|
652
|
+
* left: 100,
|
|
653
|
+
* width: 400,
|
|
654
|
+
* height: 150,
|
|
655
|
+
* rotation: 0
|
|
656
|
+
* }
|
|
657
|
+
* });
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
addElement(opts: AppElementOptions<A>): Promise<void>;
|
|
661
|
+
/**
|
|
662
|
+
* A callback that runs when:
|
|
663
|
+
*
|
|
664
|
+
* - the app element is created
|
|
665
|
+
* - the app element's data is updated
|
|
666
|
+
* - the user selects an existing app element
|
|
667
|
+
*
|
|
668
|
+
* @param handler - The callback to run when the app element changes.
|
|
669
|
+
*
|
|
670
|
+
* @example Handle element selection and update
|
|
671
|
+
* ```typescript
|
|
672
|
+
* import { initAppElement } from "@canva/design";
|
|
673
|
+
*
|
|
674
|
+
* const appElement = initAppElement<{ content: string }>({
|
|
675
|
+
* render: (data) => {
|
|
676
|
+
* return [{
|
|
677
|
+
* type: 'text',
|
|
678
|
+
* children: [data.content || 'Default text'],
|
|
679
|
+
* top: 0,
|
|
680
|
+
* left: 0,
|
|
681
|
+
* width: 200
|
|
682
|
+
* }];
|
|
683
|
+
* }
|
|
684
|
+
* });
|
|
685
|
+
*
|
|
686
|
+
* // Register a handler for element changes
|
|
687
|
+
* appElement.registerOnElementChange((element) => {
|
|
688
|
+
* if (element) {
|
|
689
|
+
* // Element is created or selected
|
|
690
|
+
* // Optionally update the element
|
|
691
|
+
* // element.update({
|
|
692
|
+
* // data: { ...element.data, lastSelected: Date.now() }
|
|
693
|
+
* // });
|
|
694
|
+
* } else {
|
|
695
|
+
* // No element is selected
|
|
696
|
+
* }
|
|
697
|
+
* });
|
|
698
|
+
* ```
|
|
699
|
+
*
|
|
700
|
+
* @example Update element when selected
|
|
701
|
+
* ```typescript
|
|
702
|
+
* import { initAppElement } from "@canva/design";
|
|
703
|
+
*
|
|
704
|
+
* const appElement = initAppElement<{
|
|
705
|
+
* content: string;
|
|
706
|
+
* metadata: { created: number; lastSelected: number };
|
|
707
|
+
* }>({
|
|
708
|
+
* render: (data) => {
|
|
709
|
+
* // Render based on data
|
|
710
|
+
* return [{
|
|
711
|
+
* type: 'text',
|
|
712
|
+
* children: [data.content || ''],
|
|
713
|
+
* top: 0,
|
|
714
|
+
* left: 0,
|
|
715
|
+
* width: 200
|
|
716
|
+
* }];
|
|
717
|
+
* }
|
|
718
|
+
* });
|
|
719
|
+
*
|
|
720
|
+
* // Update element when selected
|
|
721
|
+
* appElement.registerOnElementChange(async (element) => {
|
|
722
|
+
* if (element) {
|
|
723
|
+
* // Check if this is a newly created or a selected element
|
|
724
|
+
* const isNewElement = !element.data.metadata?.created;
|
|
725
|
+
*
|
|
726
|
+
* if (isNewElement) {
|
|
727
|
+
* // Update a new element with initial metadata
|
|
728
|
+
* await element.update({
|
|
729
|
+
* data: {
|
|
730
|
+
* ...element.data,
|
|
731
|
+
* metadata: {
|
|
732
|
+
* created: Date.now(),
|
|
733
|
+
* lastSelected: Date.now()
|
|
734
|
+
* }
|
|
735
|
+
* }
|
|
736
|
+
* });
|
|
737
|
+
* } else {
|
|
738
|
+
* // Update existing element's last selected time
|
|
739
|
+
* await element.update({
|
|
740
|
+
* data: {
|
|
741
|
+
* ...element.data,
|
|
742
|
+
* metadata: {
|
|
743
|
+
* ...element.data.metadata,
|
|
744
|
+
* lastSelected: Date.now()
|
|
745
|
+
* }
|
|
746
|
+
* }
|
|
747
|
+
* });
|
|
748
|
+
* }
|
|
749
|
+
* }
|
|
750
|
+
* });
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
registerOnElementChange(handler: AppElementChangeHandler<A>): void;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* @public
|
|
758
|
+
* Options for creating an app element client.
|
|
759
|
+
*/
|
|
760
|
+
export declare type AppElementClientConfiguration<A extends AppElementData> = {
|
|
761
|
+
/**
|
|
762
|
+
* Registers a callback that renders an app element based on the data it receives.
|
|
763
|
+
*/
|
|
764
|
+
render: AppElementRenderer<A>;
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* @public
|
|
769
|
+
* The data associated with an app element.
|
|
770
|
+
*/
|
|
771
|
+
export declare type AppElementData = Record<string, Value>;
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* @public
|
|
775
|
+
* Used to add or update an app element to the design.
|
|
776
|
+
* The update function is provided in the AppElementChangeHandler callback (registerOnElementChange).
|
|
777
|
+
*/
|
|
778
|
+
export declare type AppElementOptions<A extends AppElementData> = {
|
|
779
|
+
/**
|
|
780
|
+
* The data to attach to the app element.
|
|
781
|
+
*/
|
|
782
|
+
data: A;
|
|
783
|
+
/**
|
|
784
|
+
* The position, dimensions, and rotation of the app element.
|
|
785
|
+
*/
|
|
786
|
+
placement?: Placement;
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* @public
|
|
791
|
+
* A callback function that renders an app element based on the data it receives.
|
|
792
|
+
* @param appElementData - The data the callback must use to render the app element.
|
|
793
|
+
*/
|
|
794
|
+
export declare type AppElementRenderer<A extends AppElementData> = (appElementData: A) => AppElementRendererOutput;
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* @public
|
|
798
|
+
* An array of one or more elements to render as output of an app element.
|
|
799
|
+
*/
|
|
800
|
+
export declare type AppElementRendererOutput = GroupContentAtPoint[];
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* @public
|
|
804
|
+
* A unique identifier that references an app runtime process
|
|
805
|
+
*/
|
|
806
|
+
export declare type AppProcessId = string & {
|
|
807
|
+
__appProcessId: never;
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* @public
|
|
812
|
+
* Audio track to be added to the design at the end of a drag event.
|
|
813
|
+
*/
|
|
814
|
+
export declare type AudioDragConfig = {
|
|
815
|
+
/**
|
|
816
|
+
* The type of element.
|
|
817
|
+
*/
|
|
818
|
+
type: 'audio';
|
|
819
|
+
/**
|
|
820
|
+
* A function that returns a reference (ref) to an audio asset in Canva's backend.
|
|
821
|
+
*/
|
|
822
|
+
resolveAudioRef: () => Promise<{
|
|
823
|
+
ref: AudioRef;
|
|
824
|
+
}>;
|
|
825
|
+
/**
|
|
826
|
+
* The duration of the audio track, in milliseconds.
|
|
827
|
+
*/
|
|
828
|
+
durationMs: number;
|
|
829
|
+
/**
|
|
830
|
+
* A human readable title for the audio track.
|
|
831
|
+
*/
|
|
832
|
+
title: string;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* @public
|
|
837
|
+
* A unique identifier that references an audio asset in Canva's backend.
|
|
838
|
+
*/
|
|
839
|
+
export declare type AudioRef = string & {
|
|
840
|
+
__audioRef: never;
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* @public
|
|
845
|
+
* An audio track that can be added to a design.
|
|
846
|
+
*/
|
|
847
|
+
export declare type AudioTrack = {
|
|
848
|
+
/**
|
|
849
|
+
* A unique identifier that points to an audio asset in Canva's backend.
|
|
850
|
+
*/
|
|
851
|
+
ref: AudioRef;
|
|
852
|
+
};
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* @public
|
|
856
|
+
* A segment of a richtext range.
|
|
857
|
+
*/
|
|
858
|
+
export declare type Bounds = {
|
|
859
|
+
/**
|
|
860
|
+
* The starting position of the segment.
|
|
861
|
+
*
|
|
862
|
+
* @remarks
|
|
863
|
+
* This is zero-based, meaning the first character of the range is at index 0.
|
|
864
|
+
*/
|
|
865
|
+
index: number;
|
|
866
|
+
/**
|
|
867
|
+
* The number of characters in the segment, starting from the index.
|
|
868
|
+
*/
|
|
869
|
+
length: number;
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* @deprecated
|
|
874
|
+
* @public
|
|
875
|
+
* A position, rotation, and set of dimensions.
|
|
876
|
+
*
|
|
877
|
+
* @remarks
|
|
878
|
+
* The position and dimensions are relative to the container.
|
|
879
|
+
*/
|
|
880
|
+
export declare type Box = Point & (WidthAndHeight | Width | Height);
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* @public
|
|
884
|
+
* An alias for the BulkCreateLauncher interface, providing access to bulk create related functionality
|
|
885
|
+
*/
|
|
886
|
+
export declare const bulkCreate: BulkCreateLauncher;
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* @public
|
|
890
|
+
* Provides methods for launching the bulk create panel.
|
|
891
|
+
*/
|
|
892
|
+
export declare type BulkCreateLauncher = {
|
|
893
|
+
/**
|
|
894
|
+
* @public
|
|
895
|
+
* Launches the design bulk create with the data connector intent.
|
|
896
|
+
* @param opts - Options for configuring the bulk create panel.
|
|
897
|
+
* @throws unsupported_surface code if not invoked by the design editor intent.
|
|
898
|
+
*
|
|
899
|
+
* @example Launch the bulk create panel with the same app
|
|
900
|
+
* ```typescript
|
|
901
|
+
* import { bulkCreate } from "@canva/design";
|
|
902
|
+
* import { features } from "@canva/platform";
|
|
903
|
+
*
|
|
904
|
+
* if (features.isSupported(bulkCreate.launch)) {
|
|
905
|
+
* await bulkCreate.launch({ withDataConnector: 'self' });
|
|
906
|
+
* }
|
|
907
|
+
* ```
|
|
908
|
+
*/
|
|
909
|
+
launch(opts: LaunchBulkCreateOpts): Promise<void>;
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* @public
|
|
914
|
+
* An individual cell in a table element.
|
|
915
|
+
*/
|
|
916
|
+
export declare type Cell = {
|
|
917
|
+
/**
|
|
918
|
+
* The attributes of the cell.
|
|
919
|
+
*/
|
|
920
|
+
attributes?: CellAttributes;
|
|
921
|
+
/**
|
|
922
|
+
* The number of columns that the cell occupies.
|
|
923
|
+
*/
|
|
924
|
+
colSpan?: number;
|
|
925
|
+
/**
|
|
926
|
+
* The number of rows that the cell occupies.
|
|
927
|
+
*/
|
|
928
|
+
rowSpan?: number;
|
|
929
|
+
} & CellContent;
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* @public
|
|
933
|
+
* Additional attributes of table cell.
|
|
934
|
+
*/
|
|
935
|
+
declare type CellAttributes = {
|
|
936
|
+
/**
|
|
937
|
+
* The background color of the cell, as a hex code.
|
|
938
|
+
*/
|
|
939
|
+
backgroundColor?: string;
|
|
940
|
+
} & TextAttributes;
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* @public
|
|
944
|
+
* The content of a table element's cell.
|
|
945
|
+
* Cell only supports plain text.
|
|
946
|
+
*/
|
|
947
|
+
declare type CellContent = {
|
|
948
|
+
/**
|
|
949
|
+
* Indicates that the cell doesn't have any content.
|
|
950
|
+
*/
|
|
951
|
+
type: 'empty';
|
|
952
|
+
} | {
|
|
953
|
+
/**
|
|
954
|
+
* Indicates that the cell contains plaintext content.
|
|
955
|
+
*/
|
|
956
|
+
type: 'string';
|
|
957
|
+
/**
|
|
958
|
+
* The plaintext content of the cell.
|
|
959
|
+
*
|
|
960
|
+
* @remarks
|
|
961
|
+
* If an empty string is provided, the `type` will change to `"empty"`.
|
|
962
|
+
*/
|
|
963
|
+
value: string;
|
|
964
|
+
};
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Image element or content to be added to the design at the end of a drag event.
|
|
968
|
+
*/
|
|
969
|
+
declare type CommonImageDragConfig = {
|
|
970
|
+
/**
|
|
971
|
+
* The type of element.
|
|
972
|
+
*/
|
|
973
|
+
type: 'image';
|
|
974
|
+
/**
|
|
975
|
+
* The dimensions of the preview image.
|
|
976
|
+
*/
|
|
977
|
+
previewSize: Dimensions;
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* @public
|
|
982
|
+
* A snapshot of content from a user's design.
|
|
983
|
+
*/
|
|
984
|
+
export declare interface ContentDraft<T> {
|
|
985
|
+
/**
|
|
986
|
+
* The individual content items that exist within the snapshot.
|
|
987
|
+
*
|
|
988
|
+
* @remarks
|
|
989
|
+
* Any changes made to this array won't be reflected in the user's design until the `save` method is called.
|
|
990
|
+
*/
|
|
991
|
+
readonly contents: readonly T[];
|
|
992
|
+
/**
|
|
993
|
+
* Saves changes made to the content items in the `contents` array.
|
|
994
|
+
*
|
|
995
|
+
* @remarks
|
|
996
|
+
* Once this method is called:
|
|
997
|
+
*
|
|
998
|
+
* - Any changes the app has made to to the content will be reflected in the user's design.
|
|
999
|
+
* - Any changes the user has made to the content since the snapshot was created may be overwritten.
|
|
1000
|
+
* - Only properties that are different from the original state will be written to the design.
|
|
1001
|
+
*
|
|
1002
|
+
* @example Save changes to selected text
|
|
1003
|
+
* ```typescript
|
|
1004
|
+
* import { selection } from "@canva/design";
|
|
1005
|
+
*
|
|
1006
|
+
* selection.registerOnChange({
|
|
1007
|
+
* scope: 'plaintext',
|
|
1008
|
+
* onChange: async (event) => {
|
|
1009
|
+
* if (event.count > 0) {
|
|
1010
|
+
* const draft = await event.read();
|
|
1011
|
+
*
|
|
1012
|
+
* // Make changes to the content
|
|
1013
|
+
* for (const content of draft.contents) {
|
|
1014
|
+
* content.text = content.text.toUpperCase();
|
|
1015
|
+
* }
|
|
1016
|
+
*
|
|
1017
|
+
* // Save the changes to the design
|
|
1018
|
+
* await draft.save();
|
|
1019
|
+
* }
|
|
1020
|
+
* }
|
|
1021
|
+
* });
|
|
1022
|
+
* ```
|
|
1023
|
+
*
|
|
1024
|
+
* @example Modify then save rich text content
|
|
1025
|
+
* ```typescript
|
|
1026
|
+
* import { selection } from "@canva/design";
|
|
1027
|
+
*
|
|
1028
|
+
* selection.registerOnChange({
|
|
1029
|
+
* scope: 'richtext',
|
|
1030
|
+
* onChange: async (event) => {
|
|
1031
|
+
* if (event.count > 0) {
|
|
1032
|
+
* const draft = await event.read();
|
|
1033
|
+
* const range = draft.contents[0];
|
|
1034
|
+
*
|
|
1035
|
+
* // Get the plain text
|
|
1036
|
+
* const text = range.readPlaintext();
|
|
1037
|
+
*
|
|
1038
|
+
* // Apply formatting to the entire text
|
|
1039
|
+
* range.formatText(
|
|
1040
|
+
* { index: 0, length: text.length },
|
|
1041
|
+
* { fontWeight: 'bold', color: '#0066CC' }
|
|
1042
|
+
* );
|
|
1043
|
+
*
|
|
1044
|
+
* // Save the formatted text back to the design
|
|
1045
|
+
* await draft.save();
|
|
1046
|
+
* }
|
|
1047
|
+
* }
|
|
1048
|
+
* });
|
|
1049
|
+
* ```
|
|
1050
|
+
*/
|
|
1051
|
+
save(): Promise<void>;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* @public
|
|
1056
|
+
* A type of content that can be read from a user's design.
|
|
1057
|
+
*/
|
|
1058
|
+
export declare type ContentType = 'richtext';
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* @public
|
|
1062
|
+
* Options for configuring where content in a design should be queried from.
|
|
1063
|
+
*/
|
|
1064
|
+
export declare type ContextOptions = {
|
|
1065
|
+
target: 'current_page';
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* @public
|
|
1070
|
+
* A set of X and Y coordinates.
|
|
1071
|
+
*/
|
|
1072
|
+
export declare type Coordinates = {
|
|
1073
|
+
/**
|
|
1074
|
+
* X coordinate, in pixels.
|
|
1075
|
+
*/
|
|
1076
|
+
x: number;
|
|
1077
|
+
/**
|
|
1078
|
+
* Y coordinate, in pixels.
|
|
1079
|
+
*/
|
|
1080
|
+
y: number;
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* @public
|
|
1085
|
+
* Creates a new RichtextRange object, which contains methods to manipulate text.
|
|
1086
|
+
*
|
|
1087
|
+
* @example Create formatted text range
|
|
1088
|
+
* ```typescript
|
|
1089
|
+
* import { createRichtextRange } from "@canva/design";
|
|
1090
|
+
* import type { InlineFormatting } from "@canva/design";
|
|
1091
|
+
*
|
|
1092
|
+
* const range = createRichtextRange();
|
|
1093
|
+
*
|
|
1094
|
+
* range.appendText('Hello World', {
|
|
1095
|
+
* color: '#000000',
|
|
1096
|
+
* fontWeight: 'bold'
|
|
1097
|
+
* } as InlineFormatting);
|
|
1098
|
+
* ```
|
|
1099
|
+
*
|
|
1100
|
+
* @example Format paragraph styles
|
|
1101
|
+
* ```typescript
|
|
1102
|
+
* import { createRichtextRange } from "@canva/design";
|
|
1103
|
+
* import type { RichtextFormatting } from "@canva/design";
|
|
1104
|
+
*
|
|
1105
|
+
* const range = createRichtextRange();
|
|
1106
|
+
*
|
|
1107
|
+
* const bounds = range.appendText('Centered Title\n');
|
|
1108
|
+
* range.formatParagraph(bounds.bounds, {
|
|
1109
|
+
* fontSize: 32,
|
|
1110
|
+
* textAlign: 'center'
|
|
1111
|
+
* } as RichtextFormatting);
|
|
1112
|
+
* ```
|
|
1113
|
+
*
|
|
1114
|
+
* @example Create bulleted list
|
|
1115
|
+
* ```typescript
|
|
1116
|
+
* import { createRichtextRange } from "@canva/design";
|
|
1117
|
+
*
|
|
1118
|
+
* const range = createRichtextRange();
|
|
1119
|
+
*
|
|
1120
|
+
* const item = range.appendText('List item\n');
|
|
1121
|
+
* range.formatParagraph(item.bounds, {
|
|
1122
|
+
* fontSize: 16,
|
|
1123
|
+
* listLevel: 1,
|
|
1124
|
+
* listMarker: 'disc'
|
|
1125
|
+
* });
|
|
1126
|
+
* ```
|
|
1127
|
+
*
|
|
1128
|
+
* @example Extract text content
|
|
1129
|
+
* ```typescript
|
|
1130
|
+
* import { createRichtextRange } from "@canva/design";
|
|
1131
|
+
*
|
|
1132
|
+
* const range = createRichtextRange();
|
|
1133
|
+
* range.appendText('Sample text');
|
|
1134
|
+
*
|
|
1135
|
+
* // Get plain text content
|
|
1136
|
+
* const text = range.readPlaintext();
|
|
1137
|
+
*
|
|
1138
|
+
* // Get formatted regions
|
|
1139
|
+
* const regions = range.readTextRegions();
|
|
1140
|
+
* ```
|
|
1141
|
+
*
|
|
1142
|
+
* @example Replace text with formatting
|
|
1143
|
+
* ```typescript
|
|
1144
|
+
* import { createRichtextRange } from "@canva/design";
|
|
1145
|
+
*
|
|
1146
|
+
* const range = createRichtextRange();
|
|
1147
|
+
* range.appendText('Original text');
|
|
1148
|
+
*
|
|
1149
|
+
* // Replace text while adding formatting
|
|
1150
|
+
* range.replaceText(
|
|
1151
|
+
* { index: 0, length: range.readPlaintext().length },
|
|
1152
|
+
* 'Modified',
|
|
1153
|
+
* { color: '#0066CC', decoration: 'underline' }
|
|
1154
|
+
* );
|
|
1155
|
+
* ```
|
|
1156
|
+
*/
|
|
1157
|
+
export declare const createRichtextRange: () => RichtextRange;
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* @public
|
|
1161
|
+
* Describes a part of a design.
|
|
1162
|
+
*/
|
|
1163
|
+
export declare type DesignContext = DesignContextOptions['type'];
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* @public
|
|
1167
|
+
* Options for configuring which part of a design to read.
|
|
1168
|
+
*/
|
|
1169
|
+
declare type DesignContextOptions = {
|
|
1170
|
+
/**
|
|
1171
|
+
* The type of context.
|
|
1172
|
+
*/
|
|
1173
|
+
type: 'current_page';
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
/**
|
|
1177
|
+
* @public
|
|
1178
|
+
* Provides methods for reading and updating the structure and content of a design.
|
|
1179
|
+
*/
|
|
1180
|
+
export declare namespace DesignEditing {
|
|
1181
|
+
/**
|
|
1182
|
+
* @public
|
|
1183
|
+
* Options for creating an image fill in the element state builder
|
|
1184
|
+
*/
|
|
1185
|
+
export type ImageFillOpts = {
|
|
1186
|
+
/**
|
|
1187
|
+
* The type of media.
|
|
1188
|
+
*/
|
|
1189
|
+
type: 'image';
|
|
1190
|
+
/**
|
|
1191
|
+
* A unique identifier that points to an image asset in Canva's backend.
|
|
1192
|
+
*/
|
|
1193
|
+
imageRef: ImageRef;
|
|
1194
|
+
/**
|
|
1195
|
+
* If `true`, the image is flipped horizontally.
|
|
1196
|
+
*/
|
|
1197
|
+
flipX?: boolean;
|
|
1198
|
+
/**
|
|
1199
|
+
* If `true`, the image is flipped vertically.
|
|
1200
|
+
*/
|
|
1201
|
+
flipY?: boolean;
|
|
1202
|
+
};
|
|
1203
|
+
/**
|
|
1204
|
+
* @public
|
|
1205
|
+
* Options for creating a video fill in the element state builder
|
|
1206
|
+
*/
|
|
1207
|
+
export type VideoFillOpts = {
|
|
1208
|
+
/**
|
|
1209
|
+
* The type of media.
|
|
1210
|
+
*/
|
|
1211
|
+
type: 'video';
|
|
1212
|
+
/**
|
|
1213
|
+
* A unique identifier that points to a video asset in Canva's backend.
|
|
1214
|
+
*/
|
|
1215
|
+
videoRef: VideoRef;
|
|
1216
|
+
/**
|
|
1217
|
+
* If `true`, the video is flipped horizontally.
|
|
1218
|
+
*/
|
|
1219
|
+
flipX?: boolean;
|
|
1220
|
+
/**
|
|
1221
|
+
* If `true`, the video is flipped vertically.
|
|
1222
|
+
*/
|
|
1223
|
+
flipY?: boolean;
|
|
1224
|
+
};
|
|
1225
|
+
/**
|
|
1226
|
+
* @public
|
|
1227
|
+
* Options for creating a media fill in the element state builder
|
|
1228
|
+
*/
|
|
1229
|
+
export type MediaContainerOpts = ImageFillOpts | VideoFillOpts;
|
|
1230
|
+
/**
|
|
1231
|
+
* @public
|
|
1232
|
+
* Options for creating a fill in the element state builder
|
|
1233
|
+
*/
|
|
1234
|
+
export type FillOpts = {
|
|
1235
|
+
colorContainer: ColorContainerOpts;
|
|
1236
|
+
mediaContainer?: MediaContainerOpts;
|
|
1237
|
+
} | {
|
|
1238
|
+
colorContainer?: ColorContainerOpts;
|
|
1239
|
+
mediaContainer: MediaContainerOpts;
|
|
1240
|
+
};
|
|
1241
|
+
/**
|
|
1242
|
+
* @public
|
|
1243
|
+
* Options for creating a fill of a shape in the element state builder
|
|
1244
|
+
*/
|
|
1245
|
+
export type PathFillOpts = {
|
|
1246
|
+
colorContainer: ColorContainerOpts;
|
|
1247
|
+
mediaContainer?: MediaContainerOpts;
|
|
1248
|
+
isMediaEditable?: boolean;
|
|
1249
|
+
} | {
|
|
1250
|
+
colorContainer?: ColorContainerOpts;
|
|
1251
|
+
mediaContainer: MediaContainerOpts;
|
|
1252
|
+
isMediaEditable?: boolean;
|
|
1253
|
+
};
|
|
1254
|
+
/**
|
|
1255
|
+
* @public
|
|
1256
|
+
*/
|
|
1257
|
+
export type ColorContainerOpts = SolidFillState;
|
|
1258
|
+
/**
|
|
1259
|
+
* @public
|
|
1260
|
+
* Options for creating a stroke in the element state builder
|
|
1261
|
+
*/
|
|
1262
|
+
export type StrokeOpts = {
|
|
1263
|
+
/**
|
|
1264
|
+
* The weight (thickness) of the stroke.
|
|
1265
|
+
*
|
|
1266
|
+
* @remarks
|
|
1267
|
+
* - Minimum: 0
|
|
1268
|
+
* - Maximum: 100
|
|
1269
|
+
*/
|
|
1270
|
+
weight: number;
|
|
1271
|
+
/**
|
|
1272
|
+
* The color of the stroke.
|
|
1273
|
+
*/
|
|
1274
|
+
colorContainer: ColorContainerOpts;
|
|
1275
|
+
};
|
|
1276
|
+
/**
|
|
1277
|
+
* @public
|
|
1278
|
+
* Options for creating a shape path in the element state builder
|
|
1279
|
+
*/
|
|
1280
|
+
export type PathOpts = {
|
|
1281
|
+
d: string;
|
|
1282
|
+
/**
|
|
1283
|
+
* Describes how a fill is filled with color or media.
|
|
1284
|
+
*
|
|
1285
|
+
* @remarks
|
|
1286
|
+
* If both `media` and `color` are defined, `media` takes precedence.
|
|
1287
|
+
*/
|
|
1288
|
+
fill?: PathFillOpts;
|
|
1289
|
+
/**
|
|
1290
|
+
* The outline of the path.
|
|
1291
|
+
*/
|
|
1292
|
+
stroke?: StrokeOpts;
|
|
1293
|
+
};
|
|
1294
|
+
/**
|
|
1295
|
+
* @public
|
|
1296
|
+
* Options for creating a rect element.
|
|
1297
|
+
*/
|
|
1298
|
+
export type CreateRectElementOpts = {
|
|
1299
|
+
/**
|
|
1300
|
+
* The distance from the top edge of the container, in pixels.
|
|
1301
|
+
*
|
|
1302
|
+
* @remarks
|
|
1303
|
+
* - The pixels are relative to their container.
|
|
1304
|
+
* - Minimum: -32768
|
|
1305
|
+
* - Maximum: 32767
|
|
1306
|
+
*/
|
|
1307
|
+
top: number;
|
|
1308
|
+
/**
|
|
1309
|
+
* The distance from the left edge of the container, in pixels.
|
|
1310
|
+
*
|
|
1311
|
+
* @remarks
|
|
1312
|
+
* - The pixels are relative to their container.
|
|
1313
|
+
* - Minimum: -32768
|
|
1314
|
+
* - Maximum: 32767
|
|
1315
|
+
*/
|
|
1316
|
+
left: number;
|
|
1317
|
+
/**
|
|
1318
|
+
* A rotation, in degrees.
|
|
1319
|
+
*
|
|
1320
|
+
* @remarks
|
|
1321
|
+
* - Minimum: -180
|
|
1322
|
+
* - Maximum: 180
|
|
1323
|
+
*/
|
|
1324
|
+
rotation?: number;
|
|
1325
|
+
/**
|
|
1326
|
+
* Transparency as a percentage.
|
|
1327
|
+
*
|
|
1328
|
+
* @remarks
|
|
1329
|
+
* - Minimum: 0
|
|
1330
|
+
* - Maximum: 1
|
|
1331
|
+
*/
|
|
1332
|
+
transparency?: number;
|
|
1333
|
+
/**
|
|
1334
|
+
* A width, in pixels.
|
|
1335
|
+
*/
|
|
1336
|
+
width: number;
|
|
1337
|
+
/**
|
|
1338
|
+
* A height, in pixels.
|
|
1339
|
+
*/
|
|
1340
|
+
height: number;
|
|
1341
|
+
/**
|
|
1342
|
+
* Describes how a fill is filled with color or media.
|
|
1343
|
+
*
|
|
1344
|
+
* @remarks
|
|
1345
|
+
* If both `media` and `color` are defined, `media` takes precedence.
|
|
1346
|
+
*/
|
|
1347
|
+
fill?: FillOpts;
|
|
1348
|
+
/**
|
|
1349
|
+
* The outline of the rect.
|
|
1350
|
+
*/
|
|
1351
|
+
stroke?: StrokeOpts;
|
|
1352
|
+
};
|
|
1353
|
+
/**
|
|
1354
|
+
* @public
|
|
1355
|
+
* Options for creating a shape element.
|
|
1356
|
+
*/
|
|
1357
|
+
export type CreateShapeElementOpts = {
|
|
1358
|
+
/**
|
|
1359
|
+
* The distance from the top edge of the container, in pixels.
|
|
1360
|
+
*
|
|
1361
|
+
* @remarks
|
|
1362
|
+
* - The pixels are relative to their container.
|
|
1363
|
+
* - Minimum: -32768
|
|
1364
|
+
* - Maximum: 32767
|
|
1365
|
+
*/
|
|
1366
|
+
top: number;
|
|
1367
|
+
/**
|
|
1368
|
+
* The distance from the left edge of the container, in pixels.
|
|
1369
|
+
*
|
|
1370
|
+
* @remarks
|
|
1371
|
+
* - The pixels are relative to their container.
|
|
1372
|
+
* - Minimum: -32768
|
|
1373
|
+
* - Maximum: 32767
|
|
1374
|
+
*/
|
|
1375
|
+
left: number;
|
|
1376
|
+
/**
|
|
1377
|
+
* A rotation, in degrees.
|
|
1378
|
+
*
|
|
1379
|
+
* @remarks
|
|
1380
|
+
* - Minimum: -180
|
|
1381
|
+
* - Maximum: 180
|
|
1382
|
+
*/
|
|
1383
|
+
rotation?: number;
|
|
1384
|
+
/**
|
|
1385
|
+
* Transparency as a percentage.
|
|
1386
|
+
*
|
|
1387
|
+
* @remarks
|
|
1388
|
+
* - Minimum: 0
|
|
1389
|
+
* - Maximum: 1
|
|
1390
|
+
*/
|
|
1391
|
+
transparency?: number;
|
|
1392
|
+
/**
|
|
1393
|
+
* A width, in pixels.
|
|
1394
|
+
*/
|
|
1395
|
+
width: number;
|
|
1396
|
+
/**
|
|
1397
|
+
* A height, in pixels.
|
|
1398
|
+
*/
|
|
1399
|
+
height: number;
|
|
1400
|
+
/**
|
|
1401
|
+
* The scale and cropping of the shape.
|
|
1402
|
+
*/
|
|
1403
|
+
readonly viewBox: AlignedBoxState;
|
|
1404
|
+
/**
|
|
1405
|
+
* The paths that define the structure of the shape.
|
|
1406
|
+
*
|
|
1407
|
+
* @remarks
|
|
1408
|
+
* - Must have between 1 and 30 paths.
|
|
1409
|
+
* - Total size of all paths must not exceed 2kb.
|
|
1410
|
+
* - Maximum of 6 unique fill colors across all paths.
|
|
1411
|
+
*/
|
|
1412
|
+
paths: PathOpts[];
|
|
1413
|
+
};
|
|
1414
|
+
/**
|
|
1415
|
+
* @public
|
|
1416
|
+
* Options for creating an embed element.
|
|
1417
|
+
*/
|
|
1418
|
+
export type CreateEmbedElementOpts = {
|
|
1419
|
+
/**
|
|
1420
|
+
* The distance from the top edge of the container, in pixels.
|
|
1421
|
+
*
|
|
1422
|
+
* @remarks
|
|
1423
|
+
* - The pixels are relative to their container.
|
|
1424
|
+
* - Minimum: -32768
|
|
1425
|
+
* - Maximum: 32767
|
|
1426
|
+
*/
|
|
1427
|
+
top: number;
|
|
1428
|
+
/**
|
|
1429
|
+
* The distance from the left edge of the container, in pixels.
|
|
1430
|
+
*
|
|
1431
|
+
* @remarks
|
|
1432
|
+
* - The pixels are relative to their container.
|
|
1433
|
+
* - Minimum: -32768
|
|
1434
|
+
* - Maximum: 32767
|
|
1435
|
+
*/
|
|
1436
|
+
left: number;
|
|
1437
|
+
/**
|
|
1438
|
+
* A rotation, in degrees.
|
|
1439
|
+
*
|
|
1440
|
+
* @remarks
|
|
1441
|
+
* - Minimum: -180
|
|
1442
|
+
* - Maximum: 180
|
|
1443
|
+
*/
|
|
1444
|
+
rotation?: number;
|
|
1445
|
+
/**
|
|
1446
|
+
* Transparency as a percentage.
|
|
1447
|
+
*
|
|
1448
|
+
* @remarks
|
|
1449
|
+
* - Minimum: 0
|
|
1450
|
+
* - Maximum: 1
|
|
1451
|
+
*/
|
|
1452
|
+
transparency?: number;
|
|
1453
|
+
/**
|
|
1454
|
+
* A width, in pixels.
|
|
1455
|
+
*/
|
|
1456
|
+
width: number;
|
|
1457
|
+
/**
|
|
1458
|
+
* A height, in pixels.
|
|
1459
|
+
*/
|
|
1460
|
+
height: number;
|
|
1461
|
+
/**
|
|
1462
|
+
* The URL of the rich media.
|
|
1463
|
+
*
|
|
1464
|
+
* @remarks
|
|
1465
|
+
* This URL must be supported by the Iframely API.
|
|
1466
|
+
*/
|
|
1467
|
+
url: string;
|
|
1468
|
+
};
|
|
1469
|
+
/**
|
|
1470
|
+
* @public
|
|
1471
|
+
* Options for creating a text element.
|
|
1472
|
+
*/
|
|
1473
|
+
export type CreateTextElementOpts = {
|
|
1474
|
+
/**
|
|
1475
|
+
* The distance from the top edge of the container, in pixels.
|
|
1476
|
+
*
|
|
1477
|
+
* @remarks
|
|
1478
|
+
* - The pixels are relative to their container.
|
|
1479
|
+
* - Minimum: -32768
|
|
1480
|
+
* - Maximum: 32767
|
|
1481
|
+
*/
|
|
1482
|
+
top: number;
|
|
1483
|
+
/**
|
|
1484
|
+
* The distance from the left edge of the container, in pixels.
|
|
1485
|
+
*
|
|
1486
|
+
* @remarks
|
|
1487
|
+
* - The pixels are relative to their container.
|
|
1488
|
+
* - Minimum: -32768
|
|
1489
|
+
* - Maximum: 32767
|
|
1490
|
+
*/
|
|
1491
|
+
left: number;
|
|
1492
|
+
/**
|
|
1493
|
+
* A width, in pixels.
|
|
1494
|
+
*/
|
|
1495
|
+
width: number;
|
|
1496
|
+
/**
|
|
1497
|
+
* The text content.
|
|
1498
|
+
*/
|
|
1499
|
+
text: {
|
|
1500
|
+
regions: readonly TextRegion[];
|
|
1501
|
+
};
|
|
1502
|
+
/**
|
|
1503
|
+
* A rotation, in degrees.
|
|
1504
|
+
*
|
|
1505
|
+
* @remarks
|
|
1506
|
+
* - Minimum: -180
|
|
1507
|
+
* - Maximum: 180
|
|
1508
|
+
*/
|
|
1509
|
+
rotation?: number;
|
|
1510
|
+
/**
|
|
1511
|
+
* Transparency as a percentage.
|
|
1512
|
+
*
|
|
1513
|
+
* @remarks
|
|
1514
|
+
* - Minimum: 0
|
|
1515
|
+
* - Maximum: 1
|
|
1516
|
+
*/
|
|
1517
|
+
transparency?: number;
|
|
1518
|
+
};
|
|
1519
|
+
/**
|
|
1520
|
+
* @public
|
|
1521
|
+
* Provides methods for creating element states.
|
|
1522
|
+
*
|
|
1523
|
+
* @remarks
|
|
1524
|
+
* These methods don't add the elements to the design. They only return elements that can
|
|
1525
|
+
* be added to a design, such as with the `insertAfter` method.
|
|
1526
|
+
*
|
|
1527
|
+
* @preventInline
|
|
1528
|
+
*/
|
|
1529
|
+
export interface ElementStateBuilder {
|
|
1530
|
+
/**
|
|
1531
|
+
* Creates a rect element state.
|
|
1532
|
+
* @param opts - Options for creating the rect element.
|
|
1533
|
+
*/
|
|
1534
|
+
createRectElement(opts: CreateRectElementOpts): RectElementState;
|
|
1535
|
+
/**
|
|
1536
|
+
* Creates a shape element state.
|
|
1537
|
+
* @param opts - Options for creating the shape element.
|
|
1538
|
+
*/
|
|
1539
|
+
createShapeElement(opts: CreateShapeElementOpts): ShapeElementState;
|
|
1540
|
+
/**
|
|
1541
|
+
* Creates an embed element state.
|
|
1542
|
+
* @param opts - Options for creating the embed element.
|
|
1543
|
+
*/
|
|
1544
|
+
createEmbedElement(opts: CreateEmbedElementOpts): EmbedElementState;
|
|
1545
|
+
/**
|
|
1546
|
+
* Creates a text element state.
|
|
1547
|
+
* @param opts - Options for creating the text element.
|
|
1548
|
+
*/
|
|
1549
|
+
createTextElement(opts: CreateTextElementOpts): TextElementState;
|
|
1550
|
+
/**
|
|
1551
|
+
* Creates a richtext range.
|
|
1552
|
+
*/
|
|
1553
|
+
createRichtextRange(): RichtextRange;
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* @public
|
|
1557
|
+
* Async methods for handling more complex operations.
|
|
1558
|
+
*/
|
|
1559
|
+
export interface AsyncOperations {
|
|
1560
|
+
/**
|
|
1561
|
+
* Group specified elements.
|
|
1562
|
+
*
|
|
1563
|
+
* @param opts - Options for grouping elements.
|
|
1564
|
+
*
|
|
1565
|
+
* @returns a new group element containing all the given elements.
|
|
1566
|
+
*/
|
|
1567
|
+
group(opts: AsyncOperationsGroupOpts): Promise<GroupElement>;
|
|
1568
|
+
/**
|
|
1569
|
+
* Ungroup a group element.
|
|
1570
|
+
*
|
|
1571
|
+
* @param opts - Options for ungrouping a group element.
|
|
1572
|
+
*
|
|
1573
|
+
* @returns new elements that are ungrouped from the given group.
|
|
1574
|
+
*/
|
|
1575
|
+
ungroup(opts: AsyncOperationsUngroupOpts): Promise<readonly AbsoluteElement[]>;
|
|
1576
|
+
}
|
|
1577
|
+
/**
|
|
1578
|
+
* @public
|
|
1579
|
+
* Options for `group` operation.
|
|
1580
|
+
*/
|
|
1581
|
+
export interface AsyncOperationsGroupOpts {
|
|
1582
|
+
/**
|
|
1583
|
+
* Elements to be grouped.
|
|
1584
|
+
*/
|
|
1585
|
+
elements: readonly Exclude<GroupContentElement, UnsupportedElement>[];
|
|
1586
|
+
}
|
|
1587
|
+
/**
|
|
1588
|
+
* @public
|
|
1589
|
+
* Options for `ungroup` operation.
|
|
1590
|
+
*/
|
|
1591
|
+
export interface AsyncOperationsUngroupOpts {
|
|
1592
|
+
/**
|
|
1593
|
+
* Group element to be ungroup.
|
|
1594
|
+
*/
|
|
1595
|
+
element: GroupElement;
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* @public
|
|
1599
|
+
* Helpers for use with supported pages.
|
|
1600
|
+
*
|
|
1601
|
+
* @remarks
|
|
1602
|
+
* Not applicable to unsupported pages.
|
|
1603
|
+
*
|
|
1604
|
+
* @preventInline
|
|
1605
|
+
*/
|
|
1606
|
+
export type PageHelpers = AsyncOperations & {
|
|
1607
|
+
/**
|
|
1608
|
+
* Build an element state that can be used to create an element with the `insert` methods of
|
|
1609
|
+
* the page's element list
|
|
1610
|
+
*/
|
|
1611
|
+
elementStateBuilder: DesignEditing.ElementStateBuilder;
|
|
1612
|
+
};
|
|
1613
|
+
/**
|
|
1614
|
+
* @public
|
|
1615
|
+
* Session received by the `openDesign` callback when opening the current page.
|
|
1616
|
+
*/
|
|
1617
|
+
export type CurrentPageSession<Page = DesignEditing.Page, Helpers = DesignEditing.PageHelpers> = Readonly<{
|
|
1618
|
+
/**
|
|
1619
|
+
* The current page of the design.
|
|
1620
|
+
*/
|
|
1621
|
+
page: Page;
|
|
1622
|
+
/**
|
|
1623
|
+
* These are various utilities that allow apps to do more complex operations on the page.
|
|
1624
|
+
*/
|
|
1625
|
+
helpers: Helpers;
|
|
1626
|
+
/**
|
|
1627
|
+
* Saves any changes made during the session while keeping the session open.
|
|
1628
|
+
*
|
|
1629
|
+
* @remarks
|
|
1630
|
+
* - Any changes in the session are only reflected in the design after this method is called.
|
|
1631
|
+
* - Once this method is called, further changes in the session can still be made.
|
|
1632
|
+
*/
|
|
1633
|
+
sync(): Promise<void>;
|
|
1634
|
+
}>;
|
|
1635
|
+
/**
|
|
1636
|
+
* @deprecated The type has been superseded by `CurrentPageSession`.
|
|
1637
|
+
* @public
|
|
1638
|
+
* Session received by the `openDesign` callback when opening the current page.
|
|
1639
|
+
*/
|
|
1640
|
+
export type CurrentPageResult = CurrentPageSession;
|
|
1641
|
+
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* A function called for each item in the list.
|
|
1649
|
+
*
|
|
1650
|
+
* @param item - The current item in the list.
|
|
1651
|
+
*/
|
|
1652
|
+
export type ForEachCallback<M> = (item: M) => void;
|
|
1653
|
+
/**
|
|
1654
|
+
* A function that determines if an item should be included in the result.
|
|
1655
|
+
*
|
|
1656
|
+
* @param item - The item to test.
|
|
1657
|
+
* @returns `true` if the item should be included, otherwise `false`.
|
|
1658
|
+
*/
|
|
1659
|
+
export type FilterPredicate<M> = (item: M) => boolean;
|
|
1660
|
+
/**
|
|
1661
|
+
* A type predicate function that determines if an item is of a specific type.
|
|
1662
|
+
*
|
|
1663
|
+
* @param item - The item to test.
|
|
1664
|
+
* @returns `true` if the item is of type `C`, otherwise `false`.
|
|
1665
|
+
*/
|
|
1666
|
+
export type TypeFilterPredicate<M, C extends M> = (item: M) => item is C;
|
|
1667
|
+
/**
|
|
1668
|
+
* @public
|
|
1669
|
+
* A list that cannot be changed.
|
|
1670
|
+
*
|
|
1671
|
+
* @preventInline
|
|
1672
|
+
*/
|
|
1673
|
+
export interface ReadableList<M> {
|
|
1674
|
+
/**
|
|
1675
|
+
* Gets the number of items in the list.
|
|
1676
|
+
*
|
|
1677
|
+
* @returns The number of items.
|
|
1678
|
+
*/
|
|
1679
|
+
count(): number;
|
|
1680
|
+
/**
|
|
1681
|
+
* Converts the list to an array.
|
|
1682
|
+
*
|
|
1683
|
+
* @returns An array containing all items. The items are the same as in the list.
|
|
1684
|
+
*/
|
|
1685
|
+
toArray(): readonly M[];
|
|
1686
|
+
/**
|
|
1687
|
+
* Executes a function for each item in the list.
|
|
1688
|
+
*
|
|
1689
|
+
* @param callback - The function to run for each item.
|
|
1690
|
+
*/
|
|
1691
|
+
forEach(callback: ForEachCallback<M>): void;
|
|
1692
|
+
/**
|
|
1693
|
+
* Creates a new array with items that match a specific type.
|
|
1694
|
+
*
|
|
1695
|
+
* @param filter - A function that checks if an item is of type `C`.
|
|
1696
|
+
* @returns An array of items that are of type `C`.
|
|
1697
|
+
*/
|
|
1698
|
+
filter<C extends M>(filter: TypeFilterPredicate<M, C>): readonly C[];
|
|
1699
|
+
/**
|
|
1700
|
+
* Creates a new array with items that pass a test.
|
|
1701
|
+
*
|
|
1702
|
+
* @param filter - A function that tests each item. Returns `true` to keep the item.
|
|
1703
|
+
* @returns An array of items that passed the test.
|
|
1704
|
+
*/
|
|
1705
|
+
filter(filter: FilterPredicate<M>): readonly M[];
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
* @public
|
|
1709
|
+
* A list of items that can be read.
|
|
1710
|
+
*
|
|
1711
|
+
* @preventInline
|
|
1712
|
+
*/
|
|
1713
|
+
export interface ListState<T> extends Iterable<T | undefined> {
|
|
1714
|
+
join(separator?: string): string;
|
|
1715
|
+
slice(start?: number, end?: number): EditableListState<T>;
|
|
1716
|
+
indexOf(searchElement: T, fromIndex?: number): number;
|
|
1717
|
+
lastIndexOf(searchElement: T, fromIndex?: number): number;
|
|
1718
|
+
every<S extends T>(predicate: (value: T, index: number) => value is S): this is ListState<S>;
|
|
1719
|
+
every(predicate: (value: T, index: number) => unknown): boolean;
|
|
1720
|
+
some(predicate: (value: T, index: number) => unknown): boolean;
|
|
1721
|
+
forEach(callbackFn: (value: T, index: number) => void): void;
|
|
1722
|
+
map<U>(callbackFn: (value: T, index: number) => U): EditableListState<U>;
|
|
1723
|
+
filter<S extends T>(predicate: (value: T, index: number) => value is S): S[];
|
|
1724
|
+
filter(predicate: (value: T, index: number) => unknown): T[];
|
|
1725
|
+
reduce(callbackFn: (previousValue: T, currentValue: T, currentIndex: number) => T, initialValue?: T): T;
|
|
1726
|
+
reduce<U>(callbackFn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;
|
|
1727
|
+
reduceRight(callbackFn: (previousValue: T, currentValue: T, currentIndex: number) => T, initialValue?: T): T;
|
|
1728
|
+
reduceRight<U>(callbackFn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;
|
|
1729
|
+
find<S extends T>(predicate: (value: T | undefined, index: number) => value is S): S | undefined;
|
|
1730
|
+
find(predicate: (value: T | undefined, index: number) => unknown): T | undefined;
|
|
1731
|
+
flatMap<U>(callback: (value: T, index: number, array: T[]) => U | readonly U[]): U[];
|
|
1732
|
+
readonly length: number;
|
|
1733
|
+
readonly [n: number]: T;
|
|
1734
|
+
at(index: number): T | undefined;
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* @public
|
|
1738
|
+
* A list of items that can be read and updated.
|
|
1739
|
+
*/
|
|
1740
|
+
export type EditableListState<T> = ListState<T> & {
|
|
1741
|
+
length: number;
|
|
1742
|
+
pop(): T | undefined;
|
|
1743
|
+
push(...items: T[]): number;
|
|
1744
|
+
shift(): T | undefined;
|
|
1745
|
+
splice(start: number, deleteCount?: number): EditableListState<T>;
|
|
1746
|
+
splice(start: number, deleteCount: number, ...items: T[]): EditableListState<T>;
|
|
1747
|
+
unshift(...items: T[]): number;
|
|
1748
|
+
[n: number]: T;
|
|
1749
|
+
};
|
|
1750
|
+
/**
|
|
1751
|
+
* @public
|
|
1752
|
+
* A list of items that can be read and updated.
|
|
1753
|
+
*
|
|
1754
|
+
* @preventInline
|
|
1755
|
+
*/
|
|
1756
|
+
export interface List<S, M> extends ReadableList<M> {
|
|
1757
|
+
/**
|
|
1758
|
+
* Adds a copy of an item to the list and places it right before another item.
|
|
1759
|
+
*
|
|
1760
|
+
* @param ref - The existing item to place the new item before.
|
|
1761
|
+
* If `ref` is `undefined`, the new item is added at the end of the list.
|
|
1762
|
+
* If `ref` does not exist in the list, the operation fails.
|
|
1763
|
+
*
|
|
1764
|
+
* @param item - The item to add. A copy of this item will be inserted.
|
|
1765
|
+
*
|
|
1766
|
+
* @returns
|
|
1767
|
+
* The added item, or `undefined` if the operation failed.
|
|
1768
|
+
*/
|
|
1769
|
+
insertBefore(ref: M | undefined, item: S): M | undefined;
|
|
1770
|
+
/**
|
|
1771
|
+
* Adds a copy of an item to the list and places it right after another item.
|
|
1772
|
+
*
|
|
1773
|
+
* @param ref - The existing item to place the new item after.
|
|
1774
|
+
* If `ref` is `undefined`, the new item is added at the end of the list.
|
|
1775
|
+
* If `ref` does not exist in the list, the operation fails.
|
|
1776
|
+
*
|
|
1777
|
+
* @param item - The item to add. A copy of this item will be inserted.
|
|
1778
|
+
*
|
|
1779
|
+
* @returns
|
|
1780
|
+
* The added item, or `undefined` if the operation failed.
|
|
1781
|
+
*/
|
|
1782
|
+
insertAfter(ref: M | undefined, item: S): M | undefined;
|
|
1783
|
+
/**
|
|
1784
|
+
* Moves an existing item to a new position right before another item.
|
|
1785
|
+
*
|
|
1786
|
+
* @param ref - The existing item to move the item before.
|
|
1787
|
+
* If `ref` is `undefined`, the item is moved to the end of the list.
|
|
1788
|
+
* If `ref` does not exist in the list, the operation fails.
|
|
1789
|
+
*
|
|
1790
|
+
* @param item - The item to move.
|
|
1791
|
+
* The operation fails if the item is not already in the list.
|
|
1792
|
+
*/
|
|
1793
|
+
moveBefore(ref: M | undefined, item: M): void;
|
|
1794
|
+
/**
|
|
1795
|
+
* Moves an existing item to a new position right after another item.
|
|
1796
|
+
*
|
|
1797
|
+
* @param ref - The existing item to move the item after.
|
|
1798
|
+
* If `ref` is `undefined`, the item is moved to the end of the list.
|
|
1799
|
+
* If `ref` does not exist in the list, the operation fails.
|
|
1800
|
+
*
|
|
1801
|
+
* @param item - The item to move.
|
|
1802
|
+
* The operation fails if the item is not already in the list.
|
|
1803
|
+
*/
|
|
1804
|
+
moveAfter(ref: M | undefined, item: M): void;
|
|
1805
|
+
/**
|
|
1806
|
+
* Removes an item from the list.
|
|
1807
|
+
*
|
|
1808
|
+
* @param item - The item to remove from the list.
|
|
1809
|
+
*/
|
|
1810
|
+
delete(item: M): void;
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* @public
|
|
1814
|
+
* Represents something that's not supported by the Apps SDK.
|
|
1815
|
+
*/
|
|
1816
|
+
export interface Unsupported {
|
|
1817
|
+
readonly type: 'unsupported';
|
|
1818
|
+
}
|
|
1819
|
+
/**
|
|
1820
|
+
* @public
|
|
1821
|
+
* A state that creates a set of dimensions.
|
|
1822
|
+
*/
|
|
1823
|
+
export interface DimensionsState {
|
|
1824
|
+
/**
|
|
1825
|
+
* A width, in pixels.
|
|
1826
|
+
*/
|
|
1827
|
+
readonly width: number;
|
|
1828
|
+
/**
|
|
1829
|
+
* A height, in pixels.
|
|
1830
|
+
*/
|
|
1831
|
+
readonly height: number;
|
|
1832
|
+
}
|
|
1833
|
+
/**
|
|
1834
|
+
* @public
|
|
1835
|
+
* A set of dimensions.
|
|
1836
|
+
*/
|
|
1837
|
+
export type Dimensions = DimensionsState;
|
|
1838
|
+
/**
|
|
1839
|
+
* @public
|
|
1840
|
+
* A state that creates an image fill.
|
|
1841
|
+
*/
|
|
1842
|
+
export interface ImageFillState {
|
|
1843
|
+
/**
|
|
1844
|
+
* The type of media.
|
|
1845
|
+
*/
|
|
1846
|
+
readonly type: 'image';
|
|
1847
|
+
/**
|
|
1848
|
+
* A unique identifier that points to an image asset in Canva's backend.
|
|
1849
|
+
*/
|
|
1850
|
+
readonly imageRef: ImageRef;
|
|
1851
|
+
/**
|
|
1852
|
+
* If `true`, the image is flipped horizontally.
|
|
1853
|
+
*/
|
|
1854
|
+
flipX: boolean;
|
|
1855
|
+
/**
|
|
1856
|
+
* If `true`, the image is flipped vertically.
|
|
1857
|
+
*/
|
|
1858
|
+
flipY: boolean;
|
|
1859
|
+
}
|
|
1860
|
+
/**
|
|
1861
|
+
* @public
|
|
1862
|
+
* An image that fills the interior of a media.
|
|
1863
|
+
*/
|
|
1864
|
+
export type ImageFill = ImageFillState;
|
|
1865
|
+
/**
|
|
1866
|
+
* @public
|
|
1867
|
+
* A state that creates a video fill.
|
|
1868
|
+
*/
|
|
1869
|
+
export interface VideoFillState {
|
|
1870
|
+
/**
|
|
1871
|
+
* The type of media.
|
|
1872
|
+
*/
|
|
1873
|
+
readonly type: 'video';
|
|
1874
|
+
/**
|
|
1875
|
+
* A unique identifier that points to a video asset in Canva's backend.
|
|
1876
|
+
*/
|
|
1877
|
+
readonly videoRef: VideoRef;
|
|
1878
|
+
/**
|
|
1879
|
+
* If `true`, the video is flipped horizontally.
|
|
1880
|
+
*/
|
|
1881
|
+
flipX: boolean;
|
|
1882
|
+
/**
|
|
1883
|
+
* If `true`, the video is flipped vertically.
|
|
1884
|
+
*/
|
|
1885
|
+
flipY: boolean;
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* @public
|
|
1889
|
+
* A video that fills the interior of a media.
|
|
1890
|
+
*/
|
|
1891
|
+
export type VideoFill = VideoFillState;
|
|
1892
|
+
/**
|
|
1893
|
+
* @public
|
|
1894
|
+
* A state that creates a media fill.
|
|
1895
|
+
*/
|
|
1896
|
+
export type MediaFillState = ImageFillState | VideoFillState;
|
|
1897
|
+
/**
|
|
1898
|
+
* @public
|
|
1899
|
+
* A media item that fills an interior.
|
|
1900
|
+
*/
|
|
1901
|
+
export type MediaFill = ImageFill | VideoFill;
|
|
1902
|
+
/**
|
|
1903
|
+
* @public
|
|
1904
|
+
* A state that creates a solid color fill.
|
|
1905
|
+
*/
|
|
1906
|
+
export interface SolidFillState {
|
|
1907
|
+
/**
|
|
1908
|
+
* The type of color.
|
|
1909
|
+
*/
|
|
1910
|
+
readonly type: 'solid';
|
|
1911
|
+
/**
|
|
1912
|
+
* The color of the fill.
|
|
1913
|
+
* This must be a valid, six-digit hex code, prefixed with a `#` symbol.
|
|
1914
|
+
*
|
|
1915
|
+
* @remarks
|
|
1916
|
+
* - Must be six characters long.
|
|
1917
|
+
* - Must start with a `#`.
|
|
1918
|
+
* - Must use lowercase letters.
|
|
1919
|
+
* @example "#ff0099"
|
|
1920
|
+
*/
|
|
1921
|
+
color: string;
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* @public
|
|
1925
|
+
* A solid color that fills an interior.
|
|
1926
|
+
*/
|
|
1927
|
+
export type SolidFill = SolidFillState;
|
|
1928
|
+
/**
|
|
1929
|
+
* @public
|
|
1930
|
+
* A state that creates a color fill.
|
|
1931
|
+
*/
|
|
1932
|
+
export type ColorFillState = SolidFillState | Unsupported;
|
|
1933
|
+
/**
|
|
1934
|
+
* @public
|
|
1935
|
+
* A color that fills an interior.
|
|
1936
|
+
*/
|
|
1937
|
+
export type ColorFill = SolidFill | Unsupported;
|
|
1938
|
+
/**
|
|
1939
|
+
* @public
|
|
1940
|
+
* A state that creates a fill with color or media.
|
|
1941
|
+
*
|
|
1942
|
+
* @remarks
|
|
1943
|
+
* If both `media` and `color` are defined, `media` takes precedence.
|
|
1944
|
+
*/
|
|
1945
|
+
export interface FillState {
|
|
1946
|
+
/**
|
|
1947
|
+
* The media fill for the path, if any.
|
|
1948
|
+
*/
|
|
1949
|
+
mediaContainer: MediaFillState | undefined;
|
|
1950
|
+
/**
|
|
1951
|
+
* The color fill for the path, if any.
|
|
1952
|
+
*/
|
|
1953
|
+
colorContainer: ColorFillState | undefined;
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* @public
|
|
1957
|
+
* A state that creates a shape path fill with color or media.
|
|
1958
|
+
*
|
|
1959
|
+
* @remarks
|
|
1960
|
+
* If both `media` and `color` are defined, `media` takes precedence.
|
|
1961
|
+
*/
|
|
1962
|
+
export interface PathFillState {
|
|
1963
|
+
/**
|
|
1964
|
+
* Defines whether the media fill is editable.
|
|
1965
|
+
*/
|
|
1966
|
+
isMediaEditable: boolean;
|
|
1967
|
+
/**
|
|
1968
|
+
* The media fill for the path, if any.
|
|
1969
|
+
*/
|
|
1970
|
+
mediaContainer: MediaFillState | undefined;
|
|
1971
|
+
/**
|
|
1972
|
+
* The color fill for the path, if any.
|
|
1973
|
+
*/
|
|
1974
|
+
colorContainer: ColorFillState | undefined;
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* @public
|
|
1978
|
+
* Describes how a fill of a shape path is filled with color or media.
|
|
1979
|
+
*
|
|
1980
|
+
* @remarks
|
|
1981
|
+
* If both `media` and `color` are defined, `media` takes precedence.
|
|
1982
|
+
*/
|
|
1983
|
+
export type PathFill = PathFillWithEditableMedia | PathFillWithNonEditableMedia;
|
|
1984
|
+
export interface PathFillWithEditableMedia {
|
|
1985
|
+
readonly isMediaEditable: true;
|
|
1986
|
+
/**
|
|
1987
|
+
* A media fill, if any.
|
|
1988
|
+
*/
|
|
1989
|
+
readonly mediaContainer: {
|
|
1990
|
+
set(state: MediaFillState | undefined): void;
|
|
1991
|
+
ref: MediaFill | undefined;
|
|
1992
|
+
};
|
|
1993
|
+
/**
|
|
1994
|
+
* A color fill, if any.
|
|
1995
|
+
*/
|
|
1996
|
+
readonly colorContainer: {
|
|
1997
|
+
set(state: SolidFillState | undefined): void;
|
|
1998
|
+
ref: ColorFill | undefined;
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
export interface PathFillWithNonEditableMedia {
|
|
2002
|
+
readonly isMediaEditable: false;
|
|
2003
|
+
/**
|
|
2004
|
+
* A media fill, if any.
|
|
2005
|
+
* MediaFill is not editable
|
|
2006
|
+
*/
|
|
2007
|
+
readonly mediaContainer: {
|
|
2008
|
+
ref: MediaFill | undefined;
|
|
2009
|
+
};
|
|
2010
|
+
/**
|
|
2011
|
+
* A color fill, if any.
|
|
2012
|
+
*/
|
|
2013
|
+
readonly colorContainer: {
|
|
2014
|
+
set(state: SolidFillState | undefined): void;
|
|
2015
|
+
ref: ColorFill | undefined;
|
|
2016
|
+
};
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* @public
|
|
2020
|
+
* Describes how a fill is filled with color or media.
|
|
2021
|
+
*
|
|
2022
|
+
* @remarks
|
|
2023
|
+
* If both `media` and `color` are defined, `media` takes precedence.
|
|
2024
|
+
*
|
|
2025
|
+
* @preventInline
|
|
2026
|
+
*/
|
|
2027
|
+
export interface Fill {
|
|
2028
|
+
/**
|
|
2029
|
+
* A media fill, if any.
|
|
2030
|
+
*/
|
|
2031
|
+
readonly mediaContainer: {
|
|
2032
|
+
set(state: MediaFillState | undefined): void;
|
|
2033
|
+
ref: MediaFill | undefined;
|
|
2034
|
+
};
|
|
2035
|
+
/**
|
|
2036
|
+
* A color fill, if any.
|
|
2037
|
+
*/
|
|
2038
|
+
readonly colorContainer: {
|
|
2039
|
+
set(state: SolidFillState | undefined): void;
|
|
2040
|
+
ref: ColorFill | undefined;
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* @public
|
|
2045
|
+
* A state that creates the scale and cropping of a shape.
|
|
2046
|
+
*
|
|
2047
|
+
* @remarks
|
|
2048
|
+
* This is similar to the `viewBox` attribute of an `SVGElement`.
|
|
2049
|
+
*/
|
|
2050
|
+
export interface AlignedBoxState {
|
|
2051
|
+
/**
|
|
2052
|
+
* The distance of the shape from the top edge of the element, in pixels.
|
|
2053
|
+
*/
|
|
2054
|
+
readonly top: number;
|
|
2055
|
+
/**
|
|
2056
|
+
* The distance of the shape from the left edge of the element, in pixels.
|
|
2057
|
+
*/
|
|
2058
|
+
readonly left: number;
|
|
2059
|
+
/**
|
|
2060
|
+
* The width of the view box, in pixels.
|
|
2061
|
+
*/
|
|
2062
|
+
readonly width: number;
|
|
2063
|
+
/**
|
|
2064
|
+
* The height of the view box, in pixels.
|
|
2065
|
+
*/
|
|
2066
|
+
readonly height: number;
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* @public
|
|
2070
|
+
* The scale and cropping of a shape.
|
|
2071
|
+
*
|
|
2072
|
+
* @remarks
|
|
2073
|
+
* This is similar to the `viewBox` attribute of an `SVGElement`.
|
|
2074
|
+
*/
|
|
2075
|
+
export type AlignedBox = AlignedBoxState;
|
|
2076
|
+
/**
|
|
2077
|
+
* @public
|
|
2078
|
+
* A state that creates a path that defines the structure of a shape element.
|
|
2079
|
+
*/
|
|
2080
|
+
export interface PathState {
|
|
2081
|
+
/**
|
|
2082
|
+
* The shape of the path.
|
|
2083
|
+
*
|
|
2084
|
+
* @remarks
|
|
2085
|
+
* This is similar to the `d` attribute of an SVG's `path` element, with some limitations:
|
|
2086
|
+
*
|
|
2087
|
+
* - Must start with an `M` command.
|
|
2088
|
+
* - Only one `M` command is allowed.
|
|
2089
|
+
* - `Q` and `T` commands are not permitted.
|
|
2090
|
+
* - The path must be closed using a `Z` command or matching start and end coordinates.
|
|
2091
|
+
*/
|
|
2092
|
+
readonly d: string;
|
|
2093
|
+
/**
|
|
2094
|
+
* The appearance of the path's interior.
|
|
2095
|
+
*/
|
|
2096
|
+
readonly fill: PathFillState;
|
|
2097
|
+
/**
|
|
2098
|
+
* The stroke (outline) of the path, if any.
|
|
2099
|
+
*/
|
|
2100
|
+
readonly stroke: StrokeState | undefined;
|
|
2101
|
+
}
|
|
2102
|
+
/**
|
|
2103
|
+
* @public
|
|
2104
|
+
* A path that defines the structure of a shape element.
|
|
2105
|
+
*
|
|
2106
|
+
* @preventInline
|
|
2107
|
+
*/
|
|
2108
|
+
export type Path = {
|
|
2109
|
+
/**
|
|
2110
|
+
* The shape of the path.
|
|
2111
|
+
*
|
|
2112
|
+
* @remarks
|
|
2113
|
+
* This is similar to the `d` attribute of an SVG's `path` element, with some limitations:
|
|
2114
|
+
*
|
|
2115
|
+
* - Must start with an `M` command.
|
|
2116
|
+
* - Only one `M` command is allowed.
|
|
2117
|
+
* - `Q` and `T` commands are not permitted.
|
|
2118
|
+
* - The path must be closed using a `Z` command or matching start and end coordinates.
|
|
2119
|
+
*/
|
|
2120
|
+
readonly d: string;
|
|
2121
|
+
/**
|
|
2122
|
+
* The appearance of the path's interior.
|
|
2123
|
+
*/
|
|
2124
|
+
readonly fill: PathFill;
|
|
2125
|
+
/**
|
|
2126
|
+
* The stroke (outline) of the path, if any.
|
|
2127
|
+
*/
|
|
2128
|
+
readonly stroke: Stroke | undefined;
|
|
2129
|
+
};
|
|
2130
|
+
/**
|
|
2131
|
+
* @public
|
|
2132
|
+
* A state that creates an outline, such as the border of an element.
|
|
2133
|
+
*/
|
|
2134
|
+
export interface StrokeState {
|
|
2135
|
+
/**
|
|
2136
|
+
* The weight (thickness) of the stroke.
|
|
2137
|
+
*
|
|
2138
|
+
* @remarks
|
|
2139
|
+
* - Minimum: 0
|
|
2140
|
+
* - Maximum: 100
|
|
2141
|
+
*/
|
|
2142
|
+
weight: number;
|
|
2143
|
+
/**
|
|
2144
|
+
* The color of the stroke.
|
|
2145
|
+
*/
|
|
2146
|
+
colorContainer: ColorFillState;
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* @public
|
|
2150
|
+
* Represents an outline, such as the border of an element.
|
|
2151
|
+
*
|
|
2152
|
+
* @preventInline
|
|
2153
|
+
*/
|
|
2154
|
+
export type Stroke = {
|
|
2155
|
+
/**
|
|
2156
|
+
* The weight (thickness) of the stroke.
|
|
2157
|
+
*
|
|
2158
|
+
* @remarks
|
|
2159
|
+
* - Minimum: 0
|
|
2160
|
+
* - Maximum: 100
|
|
2161
|
+
*/
|
|
2162
|
+
weight: number;
|
|
2163
|
+
/**
|
|
2164
|
+
* The color of the stroke.
|
|
2165
|
+
*/
|
|
2166
|
+
readonly colorContainer: {
|
|
2167
|
+
ref: ColorFill;
|
|
2168
|
+
set(state: SolidFillState): void;
|
|
2169
|
+
};
|
|
2170
|
+
};
|
|
2171
|
+
/**
|
|
2172
|
+
* @public
|
|
2173
|
+
* The basic properties of the state of an element.
|
|
2174
|
+
*
|
|
2175
|
+
* @remarks
|
|
2176
|
+
* These properties are shared by all elements in a design.
|
|
2177
|
+
*/
|
|
2178
|
+
export interface ElementState extends DimensionsState {
|
|
2179
|
+
/**
|
|
2180
|
+
* If `true`, the element is locked and cannot be modified.
|
|
2181
|
+
*/
|
|
2182
|
+
readonly locked: boolean;
|
|
2183
|
+
/**
|
|
2184
|
+
* The distance from the top edge of the container, in pixels.
|
|
2185
|
+
*
|
|
2186
|
+
* @remarks
|
|
2187
|
+
* - The pixels are relative to their container.
|
|
2188
|
+
* - Minimum: -32768
|
|
2189
|
+
* - Maximum: 32767
|
|
2190
|
+
*/
|
|
2191
|
+
readonly top: number;
|
|
2192
|
+
/**
|
|
2193
|
+
* The distance from the left edge of the container, in pixels.
|
|
2194
|
+
*
|
|
2195
|
+
* @remarks
|
|
2196
|
+
* - The pixels are relative to their container.
|
|
2197
|
+
* - Minimum: -32768
|
|
2198
|
+
* - Maximum: 32767
|
|
2199
|
+
*/
|
|
2200
|
+
readonly left: number;
|
|
2201
|
+
/**
|
|
2202
|
+
* A rotation, in degrees.
|
|
2203
|
+
*
|
|
2204
|
+
* @remarks
|
|
2205
|
+
* - Minimum: -180
|
|
2206
|
+
* - Maximum: 180
|
|
2207
|
+
*/
|
|
2208
|
+
readonly rotation: number;
|
|
2209
|
+
/**
|
|
2210
|
+
* Transparency as a percentage.
|
|
2211
|
+
*
|
|
2212
|
+
* @remarks
|
|
2213
|
+
* - Minimum: 0
|
|
2214
|
+
* - Maximum: 1
|
|
2215
|
+
*/
|
|
2216
|
+
readonly transparency: number;
|
|
2217
|
+
}
|
|
2218
|
+
/**
|
|
2219
|
+
* @public
|
|
2220
|
+
* The basic properties of an element.
|
|
2221
|
+
*
|
|
2222
|
+
* @remarks
|
|
2223
|
+
* These properties are shared by all elements in a design.
|
|
2224
|
+
*/
|
|
2225
|
+
export type Element = DimensionsState & {
|
|
2226
|
+
/**
|
|
2227
|
+
* If `true`, the element is locked and cannot be modified.
|
|
2228
|
+
*/
|
|
2229
|
+
readonly locked: boolean;
|
|
2230
|
+
/**
|
|
2231
|
+
* The distance from the top edge of the container, in pixels.
|
|
2232
|
+
*
|
|
2233
|
+
* @remarks
|
|
2234
|
+
* - The pixels are relative to their container.
|
|
2235
|
+
* - Minimum: -32768
|
|
2236
|
+
* - Maximum: 32767
|
|
2237
|
+
*/
|
|
2238
|
+
top: number;
|
|
2239
|
+
/**
|
|
2240
|
+
* The distance from the left edge of the container, in pixels.
|
|
2241
|
+
*
|
|
2242
|
+
* @remarks
|
|
2243
|
+
* - The pixels are relative to their container.
|
|
2244
|
+
* - Minimum: -32768
|
|
2245
|
+
* - Maximum: 32767
|
|
2246
|
+
*/
|
|
2247
|
+
left: number;
|
|
2248
|
+
/**
|
|
2249
|
+
* A rotation, in degrees.
|
|
2250
|
+
*
|
|
2251
|
+
* @remarks
|
|
2252
|
+
* - Minimum: -180
|
|
2253
|
+
* - Maximum: 180
|
|
2254
|
+
*/
|
|
2255
|
+
rotation: number;
|
|
2256
|
+
/**
|
|
2257
|
+
* Transparency as a percentage.
|
|
2258
|
+
*
|
|
2259
|
+
* @remarks
|
|
2260
|
+
* - Minimum: 0
|
|
2261
|
+
* - Maximum: 1
|
|
2262
|
+
*/
|
|
2263
|
+
transparency: number;
|
|
2264
|
+
};
|
|
2265
|
+
/**
|
|
2266
|
+
* @public
|
|
2267
|
+
* A state that creates a rectangular element.
|
|
2268
|
+
*/
|
|
2269
|
+
export interface RectState {
|
|
2270
|
+
/**
|
|
2271
|
+
* The type of content.
|
|
2272
|
+
*/
|
|
2273
|
+
readonly type: 'rect';
|
|
2274
|
+
/**
|
|
2275
|
+
* The appearance of the rectangle's interior.
|
|
2276
|
+
*/
|
|
2277
|
+
readonly fill: FillState;
|
|
2278
|
+
/**
|
|
2279
|
+
* The outline of the rectangle.
|
|
2280
|
+
*/
|
|
2281
|
+
readonly stroke: StrokeState;
|
|
2282
|
+
}
|
|
2283
|
+
/**
|
|
2284
|
+
* @public
|
|
2285
|
+
* Represents a rectangular element.
|
|
2286
|
+
*/
|
|
2287
|
+
export type Rect = {
|
|
2288
|
+
/**
|
|
2289
|
+
* The element type
|
|
2290
|
+
*/
|
|
2291
|
+
readonly type: 'rect';
|
|
2292
|
+
readonly fill: Fill;
|
|
2293
|
+
/**
|
|
2294
|
+
* The outline of the rectangle.
|
|
2295
|
+
*/
|
|
2296
|
+
readonly stroke: Stroke;
|
|
2297
|
+
};
|
|
2298
|
+
/**
|
|
2299
|
+
* @public
|
|
2300
|
+
* A state that creates a vector shape element.
|
|
2301
|
+
*/
|
|
2302
|
+
export interface ShapeState {
|
|
2303
|
+
/**
|
|
2304
|
+
* The type of content.
|
|
2305
|
+
*/
|
|
2306
|
+
readonly type: 'shape';
|
|
2307
|
+
/**
|
|
2308
|
+
* The scale and cropping of the shape.
|
|
2309
|
+
*/
|
|
2310
|
+
readonly viewBox: AlignedBoxState;
|
|
2311
|
+
/**
|
|
2312
|
+
* The paths that define the structure of the shape.
|
|
2313
|
+
*
|
|
2314
|
+
* @remarks
|
|
2315
|
+
* - Must have between 1 and 30 paths.
|
|
2316
|
+
* - Total size of all paths must not exceed 2kb.
|
|
2317
|
+
* - Maximum of 6 unique fill colors across all paths.
|
|
2318
|
+
*/
|
|
2319
|
+
readonly paths: ListState<PathState>;
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* @public
|
|
2323
|
+
* Represents a vector shape element.
|
|
2324
|
+
*/
|
|
2325
|
+
export type Shape = {
|
|
2326
|
+
/**
|
|
2327
|
+
* The type of content.
|
|
2328
|
+
*/
|
|
2329
|
+
readonly type: 'shape';
|
|
2330
|
+
/**
|
|
2331
|
+
* The scale and cropping of the shape.
|
|
2332
|
+
*/
|
|
2333
|
+
readonly viewBox: AlignedBox;
|
|
2334
|
+
/**
|
|
2335
|
+
* The paths that define the structure of the shape.
|
|
2336
|
+
*/
|
|
2337
|
+
readonly paths: ReadableList<Path>;
|
|
2338
|
+
};
|
|
2339
|
+
/**
|
|
2340
|
+
* @public
|
|
2341
|
+
* A state that creates group content.
|
|
2342
|
+
*/
|
|
2343
|
+
export interface GroupState {
|
|
2344
|
+
/**
|
|
2345
|
+
* The type of content.
|
|
2346
|
+
*/
|
|
2347
|
+
readonly type: 'group';
|
|
2348
|
+
/**
|
|
2349
|
+
* The elements that exist within the group.
|
|
2350
|
+
*/
|
|
2351
|
+
readonly contents: ListState<GroupContentElementState>;
|
|
2352
|
+
}
|
|
2353
|
+
/**
|
|
2354
|
+
* @public
|
|
2355
|
+
* Represents group content.
|
|
2356
|
+
*/
|
|
2357
|
+
export type Group = {
|
|
2358
|
+
/**
|
|
2359
|
+
* The type of content.
|
|
2360
|
+
*/
|
|
2361
|
+
readonly type: 'group';
|
|
2362
|
+
/**
|
|
2363
|
+
* The elements that exist within the group.
|
|
2364
|
+
*/
|
|
2365
|
+
readonly contents: ReadableList<GroupContentElement>;
|
|
2366
|
+
};
|
|
2367
|
+
/**
|
|
2368
|
+
* @public
|
|
2369
|
+
* A state that creates rich media content.
|
|
2370
|
+
*/
|
|
2371
|
+
export interface EmbedState {
|
|
2372
|
+
/**
|
|
2373
|
+
* The type of content.
|
|
2374
|
+
*/
|
|
2375
|
+
readonly type: 'embed';
|
|
2376
|
+
/**
|
|
2377
|
+
* The URL of the rich media.
|
|
2378
|
+
*
|
|
2379
|
+
* @remarks
|
|
2380
|
+
* This URL must be supported by the Iframely API.
|
|
2381
|
+
*/
|
|
2382
|
+
readonly url: string;
|
|
2383
|
+
}
|
|
2384
|
+
/**
|
|
2385
|
+
* @public
|
|
2386
|
+
* Represents rich media content.
|
|
2387
|
+
*/
|
|
2388
|
+
export type Embed = EmbedState;
|
|
2389
|
+
/**
|
|
2390
|
+
* @public
|
|
2391
|
+
* A state that creates text content.
|
|
2392
|
+
*/
|
|
2393
|
+
export interface TextState {
|
|
2394
|
+
/**
|
|
2395
|
+
* The type of content.
|
|
2396
|
+
*/
|
|
2397
|
+
readonly type: 'text';
|
|
2398
|
+
/**
|
|
2399
|
+
* The text content.
|
|
2400
|
+
*/
|
|
2401
|
+
readonly text: {
|
|
2402
|
+
regions: ListState<TextRegion>;
|
|
2403
|
+
};
|
|
2404
|
+
}
|
|
2405
|
+
/**
|
|
2406
|
+
* @public
|
|
2407
|
+
* Represents text content.
|
|
2408
|
+
*/
|
|
2409
|
+
export type Text = {
|
|
2410
|
+
readonly type: 'text';
|
|
2411
|
+
readonly text: RichtextRange;
|
|
2412
|
+
};
|
|
2413
|
+
/**
|
|
2414
|
+
* @public
|
|
2415
|
+
* A state that creates a rectangle element.
|
|
2416
|
+
*
|
|
2417
|
+
* @remarks
|
|
2418
|
+
* The rectangle can be filled with image content, video content, or a solid color.
|
|
2419
|
+
*/
|
|
2420
|
+
export type RectElementState = RectState & ElementState;
|
|
2421
|
+
/**
|
|
2422
|
+
* @public
|
|
2423
|
+
* An element that renders a rectangle.
|
|
2424
|
+
*
|
|
2425
|
+
* @remarks
|
|
2426
|
+
* The rectangle can be filled with image content, video content, or a solid color.
|
|
2427
|
+
*/
|
|
2428
|
+
export type RectElement = Rect & Element;
|
|
2429
|
+
/**
|
|
2430
|
+
* @public
|
|
2431
|
+
* A state that creates a vector shape element.
|
|
2432
|
+
*/
|
|
2433
|
+
export type ShapeElementState = ShapeState & ElementState;
|
|
2434
|
+
/**
|
|
2435
|
+
* @public
|
|
2436
|
+
* An element that renders a vector shape.
|
|
2437
|
+
*/
|
|
2438
|
+
export type ShapeElement = Shape & Element;
|
|
2439
|
+
/**
|
|
2440
|
+
* @public
|
|
2441
|
+
* A state that creates a group element.
|
|
2442
|
+
*/
|
|
2443
|
+
export type GroupElementState = GroupState & ElementState;
|
|
2444
|
+
/**
|
|
2445
|
+
* @public
|
|
2446
|
+
* An element that renders a group of other elements.
|
|
2447
|
+
*/
|
|
2448
|
+
export type GroupElement = Group & Element;
|
|
2449
|
+
/**
|
|
2450
|
+
* @public
|
|
2451
|
+
* A state that creates an embed element, such as a YouTube video.
|
|
2452
|
+
*/
|
|
2453
|
+
export type EmbedElementState = EmbedState & ElementState;
|
|
2454
|
+
/**
|
|
2455
|
+
* @public
|
|
2456
|
+
* An element that embeds rich media, such as a YouTube video.
|
|
2457
|
+
*/
|
|
2458
|
+
export type EmbedElement = Embed & Element;
|
|
2459
|
+
/**
|
|
2460
|
+
* @public
|
|
2461
|
+
* A state that creates a text element.
|
|
2462
|
+
*/
|
|
2463
|
+
export type TextElementState = TextState & ElementState;
|
|
2464
|
+
/**
|
|
2465
|
+
* @public
|
|
2466
|
+
* An element that renders text content.
|
|
2467
|
+
*/
|
|
2468
|
+
export type TextElement = Text & Element;
|
|
2469
|
+
/**
|
|
2470
|
+
* @public
|
|
2471
|
+
* An element state that is not supported by the Apps SDK.
|
|
2472
|
+
*/
|
|
2473
|
+
export type UnsupportedElementState = Unsupported & ElementState;
|
|
2474
|
+
/**
|
|
2475
|
+
* @public
|
|
2476
|
+
* An element that is not supported by the Apps SDK.
|
|
2477
|
+
*/
|
|
2478
|
+
export type UnsupportedElement = Unsupported & Readonly<Element>;
|
|
2479
|
+
/**
|
|
2480
|
+
* @public
|
|
2481
|
+
* An element state that can exist in a group content state.
|
|
2482
|
+
*/
|
|
2483
|
+
export type GroupContentElementState = RectElementState | ShapeElementState | EmbedElementState | TextElementState | UnsupportedElementState;
|
|
2484
|
+
/**
|
|
2485
|
+
* @public
|
|
2486
|
+
* An element that can exist in a group element.
|
|
2487
|
+
*
|
|
2488
|
+
* @preventInline
|
|
2489
|
+
*/
|
|
2490
|
+
export type GroupContentElement = RectElement | ShapeElement | EmbedElement | TextElement | UnsupportedElement;
|
|
2491
|
+
/**
|
|
2492
|
+
* @public
|
|
2493
|
+
* An element state that can exist on an absolute page state.
|
|
2494
|
+
*
|
|
2495
|
+
* @preventInline
|
|
2496
|
+
*/
|
|
2497
|
+
export type AbsoluteElementState = RectElementState | ShapeElementState | GroupElementState | EmbedElementState | TextElementState | UnsupportedElementState;
|
|
2498
|
+
/**
|
|
2499
|
+
* @public
|
|
2500
|
+
* An element that can exist on an absolute page.
|
|
2501
|
+
*
|
|
2502
|
+
* @preventInline
|
|
2503
|
+
*/
|
|
2504
|
+
export type AbsoluteElement = RectElement | ShapeElement | GroupElement | EmbedElement | TextElement | UnsupportedElement;
|
|
2505
|
+
/**
|
|
2506
|
+
* @public
|
|
2507
|
+
* An element state that can be inserted into a page.
|
|
2508
|
+
*/
|
|
2509
|
+
export type InsertableElementState = RectElementState | ShapeElementState | EmbedElementState | TextElementState;
|
|
2510
|
+
/**
|
|
2511
|
+
* @public
|
|
2512
|
+
* A list of elements.
|
|
2513
|
+
*
|
|
2514
|
+
* @preventInline
|
|
2515
|
+
*/
|
|
2516
|
+
export interface ElementList extends List<AbsoluteElementState, AbsoluteElement> {
|
|
2517
|
+
insertBefore(ref: AbsoluteElement | undefined, state: EmbedElementState): EmbedElement;
|
|
2518
|
+
insertBefore(ref: AbsoluteElement | undefined, state: TextElementState): TextElement;
|
|
2519
|
+
insertBefore(ref: AbsoluteElement | undefined, state: ShapeElementState): ShapeElement;
|
|
2520
|
+
insertBefore(ref: AbsoluteElement | undefined, state: RectElementState): RectElement;
|
|
2521
|
+
insertBefore(ref: AbsoluteElement | undefined, state: InsertableElementState): AbsoluteElement;
|
|
2522
|
+
insertAfter(ref: AbsoluteElement | undefined, state: EmbedElementState): EmbedElement;
|
|
2523
|
+
insertAfter(ref: AbsoluteElement | undefined, state: TextElementState): TextElement;
|
|
2524
|
+
insertAfter(ref: AbsoluteElement | undefined, state: ShapeElementState): ShapeElement;
|
|
2525
|
+
insertAfter(ref: AbsoluteElement | undefined, state: RectElementState): RectElement;
|
|
2526
|
+
insertAfter(ref: AbsoluteElement | undefined, state: InsertableElementState): AbsoluteElement;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
/**
|
|
2530
|
+
* @public
|
|
2531
|
+
* A page with either fixed or unbounded dimensions.
|
|
2532
|
+
*
|
|
2533
|
+
* @preventInline
|
|
2534
|
+
*/
|
|
2535
|
+
export type AbsolutePage = {
|
|
2536
|
+
/**
|
|
2537
|
+
* The type of page.
|
|
2538
|
+
*/
|
|
2539
|
+
readonly type: 'absolute';
|
|
2540
|
+
/**
|
|
2541
|
+
* If `true`, the page is locked and cannot be modified.
|
|
2542
|
+
*/
|
|
2543
|
+
readonly locked: boolean;
|
|
2544
|
+
/**
|
|
2545
|
+
* The dimensions of the page. `dimensions` is undefined for whiteboard pages.
|
|
2546
|
+
*/
|
|
2547
|
+
readonly dimensions: Dimensions | undefined;
|
|
2548
|
+
/**
|
|
2549
|
+
* The background of the page. `background` is undefined for whiteboard pages.
|
|
2550
|
+
*/
|
|
2551
|
+
readonly background: Fill | undefined;
|
|
2552
|
+
/**
|
|
2553
|
+
* The elements on the page.
|
|
2554
|
+
*
|
|
2555
|
+
* @remarks
|
|
2556
|
+
* Elements are rendered in the order they appear in the list.
|
|
2557
|
+
* Later elements appear on top of earlier ones.
|
|
2558
|
+
*/
|
|
2559
|
+
readonly elements: ElementList;
|
|
2560
|
+
};
|
|
2561
|
+
|
|
2562
|
+
/**
|
|
2563
|
+
* @public
|
|
2564
|
+
* A page in a design.
|
|
2565
|
+
*
|
|
2566
|
+
* @remarks
|
|
2567
|
+
* - Currently, only absolute pages are supported.
|
|
2568
|
+
* - Other page types are represented as `Unsupported`.
|
|
2569
|
+
* - Additional page types may be supported in future releases.
|
|
2570
|
+
*/
|
|
2571
|
+
export type Page = AbsolutePage | Unsupported;
|
|
2572
|
+
|
|
2573
|
+
|
|
2574
|
+
|
|
2575
|
+
|
|
2576
|
+
|
|
2577
|
+
|
|
2578
|
+
|
|
2579
|
+
|
|
2580
|
+
|
|
2581
|
+
|
|
2582
|
+
|
|
2583
|
+
|
|
2584
|
+
|
|
2585
|
+
{};
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
/**
|
|
2589
|
+
* @public
|
|
2590
|
+
* An element that's natively supported by the Canva editor.
|
|
2591
|
+
*/
|
|
2592
|
+
export declare type DesignElement = ImageElement | VideoElement | EmbedElement | TextElement | ShapeElement | GroupElement | RichtextElement | TableElement;
|
|
2593
|
+
|
|
2594
|
+
/**
|
|
2595
|
+
* @public
|
|
2596
|
+
* Information about the design.
|
|
2597
|
+
*/
|
|
2598
|
+
export declare type DesignMetadata = {
|
|
2599
|
+
/**
|
|
2600
|
+
* The title of the user's design.
|
|
2601
|
+
* @remarks
|
|
2602
|
+
* This is optional and will be `undefined` if the user hasn't set a title.
|
|
2603
|
+
*/
|
|
2604
|
+
title?: string;
|
|
2605
|
+
/**
|
|
2606
|
+
* The default dimensions that a new page will have when it is added to a design.
|
|
2607
|
+
* It is possible for a user to resize a page without resizing the entire design, e.g. by clicking
|
|
2608
|
+
* "Expand to Whiteboard". However, there will always be a single set of default dimensions for a
|
|
2609
|
+
* design that is applied whenever a new page is created.
|
|
2610
|
+
* @remarks
|
|
2611
|
+
* This is optional and will be `undefined` if the design is unbounded (e.g. Whiteboard or Doc).
|
|
2612
|
+
*/
|
|
2613
|
+
defaultPageDimensions?: PageDimensions;
|
|
2614
|
+
/**
|
|
2615
|
+
* The information associated with each page of the design.
|
|
2616
|
+
* @remarks
|
|
2617
|
+
* The order of pages is not guaranteed.
|
|
2618
|
+
*/
|
|
2619
|
+
pageMetadata: Iterable<PageMetadata>;
|
|
2620
|
+
/**
|
|
2621
|
+
* The duration of the whole design in seconds.
|
|
2622
|
+
* @remarks
|
|
2623
|
+
* This is the precise value, which differs from what is displayed in the UI as duration in Canva UI is formatted differently.
|
|
2624
|
+
*/
|
|
2625
|
+
durationInSeconds: number;
|
|
2626
|
+
};
|
|
2627
|
+
|
|
2628
|
+
/**
|
|
2629
|
+
* @public
|
|
2630
|
+
* A callback for reading and updating part of a design.
|
|
2631
|
+
* @param session - Session received by the `openDesign` callback.
|
|
2632
|
+
*/
|
|
2633
|
+
export declare type DesignOpenCallback = (session: DesignEditing.CurrentPageSession) => Promise<void>;
|
|
2634
|
+
|
|
2635
|
+
/**
|
|
2636
|
+
* @public
|
|
2637
|
+
* Options for configuring which part of a design to read.
|
|
2638
|
+
*/
|
|
2639
|
+
export declare type DesignOpenOptions = DesignContextOptions;
|
|
2640
|
+
|
|
2641
|
+
/**
|
|
2642
|
+
* @public
|
|
2643
|
+
* Provides methods for managing the lifecycle of overlays, such as selected image overlays.
|
|
2644
|
+
*/
|
|
2645
|
+
export declare type DesignOverlay = {
|
|
2646
|
+
/**
|
|
2647
|
+
* Registers a callback that runs when the `canOpen` state of an overlay target changes.
|
|
2648
|
+
* @param opts - Options for configuring the callback.
|
|
2649
|
+
*
|
|
2650
|
+
* @example Register overlay handler
|
|
2651
|
+
* ```typescript
|
|
2652
|
+
* import { overlay } from "@canva/design";
|
|
2653
|
+
*
|
|
2654
|
+
* overlay.registerOnCanOpen({
|
|
2655
|
+
* target: 'image_selection',
|
|
2656
|
+
* onCanOpen: async (event) => {
|
|
2657
|
+
* if (event.canOpen) {
|
|
2658
|
+
* // Can open overlay for selected image
|
|
2659
|
+
* }
|
|
2660
|
+
* }
|
|
2661
|
+
* });
|
|
2662
|
+
* ```
|
|
2663
|
+
*
|
|
2664
|
+
* @example Open image editing overlay
|
|
2665
|
+
* ```typescript
|
|
2666
|
+
* import { overlay } from "@canva/design";
|
|
2667
|
+
*
|
|
2668
|
+
* overlay.registerOnCanOpen({
|
|
2669
|
+
* target: 'image_selection',
|
|
2670
|
+
* onCanOpen: async (event) => {
|
|
2671
|
+
* if (event.canOpen) {
|
|
2672
|
+
* const processId = await event.open({
|
|
2673
|
+
* launchParameters: {
|
|
2674
|
+
* mode: 'edit'
|
|
2675
|
+
* }
|
|
2676
|
+
* });
|
|
2677
|
+
* // Overlay process started, with `processId`
|
|
2678
|
+
* }
|
|
2679
|
+
* }
|
|
2680
|
+
* });
|
|
2681
|
+
* ```
|
|
2682
|
+
*
|
|
2683
|
+
* @example Open overlay with filters
|
|
2684
|
+
* ```typescript
|
|
2685
|
+
* import { overlay } from "@canva/design";
|
|
2686
|
+
*
|
|
2687
|
+
* overlay.registerOnCanOpen({
|
|
2688
|
+
* target: 'image_selection',
|
|
2689
|
+
* onCanOpen: async (event) => {
|
|
2690
|
+
* if (event.canOpen) {
|
|
2691
|
+
* await event.open({
|
|
2692
|
+
* launchParameters: {
|
|
2693
|
+
* mode: 'edit',
|
|
2694
|
+
* filters: ['brightness', 'contrast', 'saturation']
|
|
2695
|
+
* }
|
|
2696
|
+
* });
|
|
2697
|
+
* }
|
|
2698
|
+
* }
|
|
2699
|
+
* });
|
|
2700
|
+
* ```
|
|
2701
|
+
*
|
|
2702
|
+
* @example Handle overlay unavailability
|
|
2703
|
+
* ```typescript
|
|
2704
|
+
* import { overlay } from "@canva/design";
|
|
2705
|
+
*
|
|
2706
|
+
* overlay.registerOnCanOpen({
|
|
2707
|
+
* target: 'image_selection',
|
|
2708
|
+
* onCanOpen: async (event) => {
|
|
2709
|
+
* if (!event.canOpen) {
|
|
2710
|
+
* // Cannot open overlay, handle specific reasons
|
|
2711
|
+
* switch (event.reason) {
|
|
2712
|
+
* case 'no_selection':
|
|
2713
|
+
* // No image is selected
|
|
2714
|
+
* break;
|
|
2715
|
+
* case 'invalid_selection':
|
|
2716
|
+
* // Selected content cannot be edited
|
|
2717
|
+
* break;
|
|
2718
|
+
* }
|
|
2719
|
+
* }
|
|
2720
|
+
* }
|
|
2721
|
+
* });
|
|
2722
|
+
* ```
|
|
2723
|
+
*/
|
|
2724
|
+
registerOnCanOpen<Target extends OverlayTarget>(opts: {
|
|
2725
|
+
/**
|
|
2726
|
+
* The target to check the `canOpen` state of.
|
|
2727
|
+
*/
|
|
2728
|
+
target: Target;
|
|
2729
|
+
/**
|
|
2730
|
+
* A callback that runs when the `canOpen` state of the specified target changes.
|
|
2731
|
+
*
|
|
2732
|
+
* @param event - Information about whether or not an overlay can be opened for the specified target.
|
|
2733
|
+
*
|
|
2734
|
+
* @remarks
|
|
2735
|
+
* This callback fires immediately.
|
|
2736
|
+
*/
|
|
2737
|
+
onCanOpen(event: OverlayOpenableEvent<Target>): void;
|
|
2738
|
+
}): () => void;
|
|
2739
|
+
};
|
|
2740
|
+
|
|
2741
|
+
/**
|
|
2742
|
+
* @public
|
|
2743
|
+
* Provides methods for interacting with selected content.
|
|
2744
|
+
*/
|
|
2745
|
+
export declare type DesignSelection = {
|
|
2746
|
+
/**
|
|
2747
|
+
* Registers a callback that runs when the specified type of content is selected.
|
|
2748
|
+
*
|
|
2749
|
+
* @param opts - Options for configuring the content selection callback.
|
|
2750
|
+
*
|
|
2751
|
+
* @remarks
|
|
2752
|
+
* - This callback fires immediately if content is already selected when the callback is registered.
|
|
2753
|
+
* - App elements are not supported by this API. For managing selection and updates to app elements, please refer to the `initAppElement` API call for details and examples.
|
|
2754
|
+
*
|
|
2755
|
+
* @example Handling plaintext selection
|
|
2756
|
+
* ```typescript
|
|
2757
|
+
* import { selection } from "@canva/design";
|
|
2758
|
+
*
|
|
2759
|
+
* selection.registerOnChange({
|
|
2760
|
+
* scope: 'plaintext',
|
|
2761
|
+
* onChange: async (event) => {
|
|
2762
|
+
* if (event.count > 0) {
|
|
2763
|
+
* const draft = await event.read();
|
|
2764
|
+
* // Do something with the selected text, e.g. `draft.contents[0].text`
|
|
2765
|
+
* }
|
|
2766
|
+
* }
|
|
2767
|
+
* });
|
|
2768
|
+
* ```
|
|
2769
|
+
*
|
|
2770
|
+
* @example Handling image selection
|
|
2771
|
+
* ```typescript
|
|
2772
|
+
* import { selection } from "@canva/design";
|
|
2773
|
+
*
|
|
2774
|
+
* selection.registerOnChange({
|
|
2775
|
+
* scope: 'image',
|
|
2776
|
+
* onChange: async (event) => {
|
|
2777
|
+
* if (event.count > 0) {
|
|
2778
|
+
* const draft = await event.read();
|
|
2779
|
+
* // Do something with the selected image ref, e.g. `draft.contents[0].ref`
|
|
2780
|
+
* }
|
|
2781
|
+
* }
|
|
2782
|
+
* });
|
|
2783
|
+
* ```
|
|
2784
|
+
*
|
|
2785
|
+
* @example Edit selected image and upload with parentRef
|
|
2786
|
+
* ```typescript
|
|
2787
|
+
* import { selection } from "@canva/design";
|
|
2788
|
+
* import { getTemporaryUrl, upload } from "@canva/asset";
|
|
2789
|
+
*
|
|
2790
|
+
* selection.registerOnChange({
|
|
2791
|
+
* scope: 'image',
|
|
2792
|
+
* onChange: async (event) => {
|
|
2793
|
+
* if (event.count > 0) {
|
|
2794
|
+
* const draft = await event.read();
|
|
2795
|
+
*
|
|
2796
|
+
* for (const content of draft.contents) {
|
|
2797
|
+
* // Fetch a temporary URL to the original image
|
|
2798
|
+
* const { url } = await getTemporaryUrl({
|
|
2799
|
+
* type: "image",
|
|
2800
|
+
* ref: content.ref
|
|
2801
|
+
* });
|
|
2802
|
+
*
|
|
2803
|
+
* // Apply any edits you want to the image
|
|
2804
|
+
* const processedImageUrl = await applyImageEffect(url);
|
|
2805
|
+
*
|
|
2806
|
+
* // Upload the edited image with parentRef
|
|
2807
|
+
* const asset = await upload({
|
|
2808
|
+
* type: "image",
|
|
2809
|
+
* parentRef: content.ref,
|
|
2810
|
+
* url: processedImageUrl,
|
|
2811
|
+
* mimeType: "image/jpeg",
|
|
2812
|
+
* thumbnailUrl: processedImageUrl,
|
|
2813
|
+
* aiDisclosure: "app_generated"
|
|
2814
|
+
* });
|
|
2815
|
+
*
|
|
2816
|
+
* // Replace the image ref with the new image ref
|
|
2817
|
+
* content.ref = asset.ref;
|
|
2818
|
+
* }
|
|
2819
|
+
*
|
|
2820
|
+
* // Save the changes to the design
|
|
2821
|
+
* await draft.save();
|
|
2822
|
+
* }
|
|
2823
|
+
* }
|
|
2824
|
+
* });
|
|
2825
|
+
* ```
|
|
2826
|
+
*
|
|
2827
|
+
* @example Handling video selection
|
|
2828
|
+
* ```typescript
|
|
2829
|
+
* import { selection } from "@canva/design";
|
|
2830
|
+
*
|
|
2831
|
+
* selection.registerOnChange({
|
|
2832
|
+
* scope: 'video',
|
|
2833
|
+
* onChange: async (event) => {
|
|
2834
|
+
* if (event.count > 0) {
|
|
2835
|
+
* const draft = await event.read();
|
|
2836
|
+
* // Do something with the selected video ref, e.g. `draft.contents[0].ref`
|
|
2837
|
+
* }
|
|
2838
|
+
* }
|
|
2839
|
+
* });
|
|
2840
|
+
* ```
|
|
2841
|
+
*
|
|
2842
|
+
* @example Handling richtext selection
|
|
2843
|
+
* ```typescript
|
|
2844
|
+
* import { selection } from "@canva/design";
|
|
2845
|
+
*
|
|
2846
|
+
* selection.registerOnChange({
|
|
2847
|
+
* scope: 'richtext',
|
|
2848
|
+
* onChange: async (event) => {
|
|
2849
|
+
* if (event.count > 0) {
|
|
2850
|
+
* const draft = await event.read();
|
|
2851
|
+
* const range = draft.contents[0];
|
|
2852
|
+
* // Do something with the selected richtext, e.g. `range.readPlaintext()`
|
|
2853
|
+
* }
|
|
2854
|
+
* }
|
|
2855
|
+
* });
|
|
2856
|
+
* ```
|
|
2857
|
+
*/
|
|
2858
|
+
registerOnChange<Scope extends SelectionScope>(opts: {
|
|
2859
|
+
/**
|
|
2860
|
+
* The type of content that triggers a selection change event.
|
|
2861
|
+
*/
|
|
2862
|
+
scope: Scope;
|
|
2863
|
+
/**
|
|
2864
|
+
* The callback to run when the selected content changes.
|
|
2865
|
+
* @param event - Information about the selection change event.
|
|
2866
|
+
*/
|
|
2867
|
+
onChange(event: SelectionEvent<Scope>): void;
|
|
2868
|
+
}): () => void;
|
|
2869
|
+
};
|
|
2870
|
+
|
|
2871
|
+
/**
|
|
2872
|
+
* @public
|
|
2873
|
+
* JWT that contains the Design ID and App ID.
|
|
2874
|
+
*/
|
|
2875
|
+
export declare type DesignToken = {
|
|
2876
|
+
token: string;
|
|
2877
|
+
};
|
|
2878
|
+
|
|
2879
|
+
/**
|
|
2880
|
+
* @public
|
|
2881
|
+
* A set of dimensions.
|
|
2882
|
+
*/
|
|
2883
|
+
export declare type Dimensions = {
|
|
2884
|
+
/**
|
|
2885
|
+
* A width, in pixels.
|
|
2886
|
+
*/
|
|
2887
|
+
width: number;
|
|
2888
|
+
/**
|
|
2889
|
+
* A height, in pixels.
|
|
2890
|
+
*/
|
|
2891
|
+
height: number;
|
|
2892
|
+
};
|
|
2893
|
+
|
|
2894
|
+
/**
|
|
2895
|
+
* @public
|
|
2896
|
+
* An event that occurs when a user starts dragging an HTML element.
|
|
2897
|
+
*/
|
|
2898
|
+
export declare type DragStartEvent<E extends Element> = Pick<DragEvent, 'dataTransfer' | 'currentTarget' | 'preventDefault' | 'clientX' | 'clientY'> & {
|
|
2899
|
+
currentTarget: E;
|
|
2900
|
+
};
|
|
2901
|
+
|
|
2902
|
+
/**
|
|
2903
|
+
* @public
|
|
2904
|
+
* Reads and edits content of the specified type from the user's design.
|
|
2905
|
+
* @param options - Options for configuring how a design is read.
|
|
2906
|
+
* @param callback - A callback for operating on the read content.
|
|
2907
|
+
*
|
|
2908
|
+
* @example Read richtext content
|
|
2909
|
+
* ```typescript
|
|
2910
|
+
* import { editContent } from "@canva/design";
|
|
2911
|
+
*
|
|
2912
|
+
* await editContent(
|
|
2913
|
+
* { contentType: 'richtext', target: 'current_page' },
|
|
2914
|
+
* async (session) => {
|
|
2915
|
+
* // Do something with the richtext content, e.g. `session.contents`
|
|
2916
|
+
* }
|
|
2917
|
+
* );
|
|
2918
|
+
* ```
|
|
2919
|
+
*/
|
|
2920
|
+
export declare const editContent: (options: EditContentOptions, callback: EditContentCallback) => Promise<void>;
|
|
2921
|
+
|
|
2922
|
+
/**
|
|
2923
|
+
* @public
|
|
2924
|
+
* A callback for reading and updating the requested design content.
|
|
2925
|
+
* @param session - The result of reading the content in the design.
|
|
2926
|
+
*/
|
|
2927
|
+
export declare type EditContentCallback = (session: RichtextContentSession) => Promise<void> | void;
|
|
2928
|
+
|
|
2929
|
+
/**
|
|
2930
|
+
* @public
|
|
2931
|
+
* Options for configuring how the design content is read.
|
|
2932
|
+
*/
|
|
2933
|
+
export declare type EditContentOptions = {
|
|
2934
|
+
/**
|
|
2935
|
+
* The type of content to edit from the user's design
|
|
2936
|
+
*/
|
|
2937
|
+
contentType: ContentType;
|
|
2938
|
+
} & ContextOptions;
|
|
2939
|
+
|
|
2940
|
+
/**
|
|
2941
|
+
* @public
|
|
2942
|
+
* Elements targeting a cursor are a subset of the base Element
|
|
2943
|
+
**/
|
|
2944
|
+
export declare type ElementAtCursor = ImageElement | VideoElement | EmbedElement | TextElement | RichtextElement | TableElement;
|
|
2945
|
+
|
|
2946
|
+
/**
|
|
2947
|
+
* @public
|
|
2948
|
+
* An element that's natively supported by the Canva editor and has positional properties.
|
|
2949
|
+
*/
|
|
2950
|
+
export declare type ElementAtPoint = ImageElementAtPoint | VideoElementAtPoint | EmbedElementAtPoint | TextElementAtPoint | ShapeElementAtPoint | GroupElementAtPoint | RichtextElementAtPoint;
|
|
2951
|
+
|
|
2952
|
+
/**
|
|
2953
|
+
* @public
|
|
2954
|
+
* Embed element to be added to the design at the end of a drag event.
|
|
2955
|
+
*/
|
|
2956
|
+
export declare type EmbedDragConfig = {
|
|
2957
|
+
/**
|
|
2958
|
+
* The type of element.
|
|
2959
|
+
*/
|
|
2960
|
+
type: 'embed';
|
|
2961
|
+
/**
|
|
2962
|
+
* The dimensions of the preview image.
|
|
2963
|
+
*/
|
|
2964
|
+
previewSize: Dimensions;
|
|
2965
|
+
/**
|
|
2966
|
+
* The URL of an image to display under the user's cursor during the drag and drop event.
|
|
2967
|
+
*/
|
|
2968
|
+
previewUrl: string;
|
|
2969
|
+
/**
|
|
2970
|
+
* The URL of media that can be embedded, such as the URL of a YouTube video.
|
|
2971
|
+
*
|
|
2972
|
+
* @remarks
|
|
2973
|
+
* This URL must be supported by the Iframely API.
|
|
2974
|
+
*/
|
|
2975
|
+
embedUrl: string;
|
|
2976
|
+
};
|
|
2977
|
+
|
|
2978
|
+
/**
|
|
2979
|
+
* @public
|
|
2980
|
+
* An element that renders rich media, such as a YouTube video.
|
|
2981
|
+
*/
|
|
2982
|
+
export declare type EmbedElement = {
|
|
2983
|
+
/**
|
|
2984
|
+
* The type of element.
|
|
2985
|
+
*/
|
|
2986
|
+
type: 'embed';
|
|
2987
|
+
/**
|
|
2988
|
+
* The URL of the rich media.
|
|
2989
|
+
*
|
|
2990
|
+
* @remarks
|
|
2991
|
+
* This URL must be supported by the Iframely API.
|
|
2992
|
+
*/
|
|
2993
|
+
url: string;
|
|
2994
|
+
};
|
|
2995
|
+
|
|
2996
|
+
/**
|
|
2997
|
+
* @public
|
|
2998
|
+
* An element that renders rich media, such as a YouTube video, and has positional properties.
|
|
2999
|
+
*/
|
|
3000
|
+
export declare type EmbedElementAtPoint = EmbedElement & Point & (WidthAndHeight | Width | Height);
|
|
3001
|
+
|
|
3002
|
+
/**
|
|
3003
|
+
* @public
|
|
3004
|
+
* The result when a user abandons the export flow, such as by closing the export menu.
|
|
3005
|
+
*/
|
|
3006
|
+
export declare type ExportAborted = {
|
|
3007
|
+
/**
|
|
3008
|
+
* The status of the export flow.
|
|
3009
|
+
*/
|
|
3010
|
+
status: 'aborted';
|
|
3011
|
+
};
|
|
3012
|
+
|
|
3013
|
+
/**
|
|
3014
|
+
* @public
|
|
3015
|
+
* The exported file.
|
|
3016
|
+
*/
|
|
3017
|
+
export declare type ExportBlob = {
|
|
3018
|
+
/**
|
|
3019
|
+
* The URL of the exported design.
|
|
3020
|
+
*
|
|
3021
|
+
* @remarks
|
|
3022
|
+
* If a user's design contains multiple pages but is exported in a format that doesn't support multiple pages,
|
|
3023
|
+
* by default this URL will point to a ZIP file that contains each page as a separate file.
|
|
3024
|
+
*
|
|
3025
|
+
* If the user has configured the export to not zip the exported files (using the `zipped` property), this URL will point to a single file.
|
|
3026
|
+
*
|
|
3027
|
+
* For example:
|
|
3028
|
+
*
|
|
3029
|
+
* - If a single-page design is exported as a JPG, the URL will point to a JPG file.
|
|
3030
|
+
* - If a multi-page design is exported as a JPG, the URL will point to a ZIP file that contains a JPG file for each page.
|
|
3031
|
+
* - If a multi-page design is exported as a JPG and the user has set `zipped` to `never` for JPGs, the URL will point to a JPG file and will be one of multiple urls in the exportBlobs array.
|
|
3032
|
+
* - If a multi-page design is exported as a PDF file, the URL will point to a PDF file.
|
|
3033
|
+
* - If a multi-page design is exported as a VIDEO file and the user has set `zipped` to `always` for VIDEOs, the URL will point to a ZIP that contains a VIDEO file.
|
|
3034
|
+
*
|
|
3035
|
+
* The following file types support multiple pages:
|
|
3036
|
+
*
|
|
3037
|
+
* - `"GIF"`
|
|
3038
|
+
* - `"PDF_STANDARD"`
|
|
3039
|
+
* - `"PPTX"`
|
|
3040
|
+
* - `"VIDEO"`
|
|
3041
|
+
*
|
|
3042
|
+
* The following file types do not support multiple pages:
|
|
3043
|
+
*
|
|
3044
|
+
* - `"JPG"`
|
|
3045
|
+
* - `"PNG"`
|
|
3046
|
+
* - `"SVG"`
|
|
3047
|
+
*/
|
|
3048
|
+
url: string;
|
|
3049
|
+
};
|
|
3050
|
+
|
|
3051
|
+
/**
|
|
3052
|
+
* @public
|
|
3053
|
+
* The result when a user successfully completes an export flow.
|
|
3054
|
+
*/
|
|
3055
|
+
export declare type ExportCompleted = {
|
|
3056
|
+
/**
|
|
3057
|
+
* The status of the export flow.
|
|
3058
|
+
*/
|
|
3059
|
+
status: 'completed';
|
|
3060
|
+
/**
|
|
3061
|
+
* The title of the design, if set by the user.
|
|
3062
|
+
*/
|
|
3063
|
+
title?: string;
|
|
3064
|
+
/**
|
|
3065
|
+
* The exported files.
|
|
3066
|
+
*
|
|
3067
|
+
* @remarks
|
|
3068
|
+
* This array can contain a single link either to a file or a ZIP, or multiple links to individual files.
|
|
3069
|
+
*/
|
|
3070
|
+
exportBlobs: ExportBlob[];
|
|
3071
|
+
};
|
|
3072
|
+
|
|
3073
|
+
/**
|
|
3074
|
+
* @public
|
|
3075
|
+
* The types of files that Canva supports for exported designs.
|
|
3076
|
+
*/
|
|
3077
|
+
export declare type ExportFileType = 'png' | 'jpg' | 'pdf_standard' | 'video' | 'gif' | 'pptx' | 'svg';
|
|
3078
|
+
|
|
3079
|
+
/**
|
|
3080
|
+
* @public
|
|
3081
|
+
* Object representation of the supported file types with properties where applicable.
|
|
3082
|
+
*/
|
|
3083
|
+
export declare type ExportFileTypeWithProperties = ExportImageFileType | ExportVideoFileType | ExportPrintFileType;
|
|
3084
|
+
|
|
3085
|
+
/**
|
|
3086
|
+
* @public
|
|
3087
|
+
* Supported image file types with properties.
|
|
3088
|
+
*
|
|
3089
|
+
* @remarks
|
|
3090
|
+
* Zip behavior for image file types:
|
|
3091
|
+
* - `auto` (default): Files are zipped together if the design has multiple pages, unzipped if it has one page.
|
|
3092
|
+
* - `always`: Files are always zipped into a single zip file, regardless of page count.
|
|
3093
|
+
* - `never`: Files are never zipped, providing an array of files.
|
|
3094
|
+
*/
|
|
3095
|
+
export declare type ExportImageFileType = {
|
|
3096
|
+
type: 'png' | 'jpg' | 'svg';
|
|
3097
|
+
zipped?: ZipBehavior;
|
|
3098
|
+
};
|
|
3099
|
+
|
|
3100
|
+
/**
|
|
3101
|
+
* @public
|
|
3102
|
+
* Supported print file types.
|
|
3103
|
+
*/
|
|
3104
|
+
export declare type ExportPrintFileType = {
|
|
3105
|
+
type: 'pdf_standard' | 'pptx';
|
|
3106
|
+
};
|
|
3107
|
+
|
|
3108
|
+
/**
|
|
3109
|
+
* @public
|
|
3110
|
+
* Options for configuring the export of a design.
|
|
3111
|
+
*/
|
|
3112
|
+
export declare type ExportRequest = {
|
|
3113
|
+
/**
|
|
3114
|
+
* The types of files the user can export their design as.
|
|
3115
|
+
*
|
|
3116
|
+
* @remarks
|
|
3117
|
+
* You must provide at least one file type.
|
|
3118
|
+
*/
|
|
3119
|
+
acceptedFileTypes: (ExportFileType | ExportFileTypeWithProperties)[];
|
|
3120
|
+
};
|
|
3121
|
+
|
|
3122
|
+
/**
|
|
3123
|
+
* @public
|
|
3124
|
+
* The result of exporting a design.
|
|
3125
|
+
*/
|
|
3126
|
+
export declare type ExportResponse = ExportCompleted | ExportAborted;
|
|
3127
|
+
|
|
3128
|
+
/**
|
|
3129
|
+
* @public
|
|
3130
|
+
* Supported video file types with properties.
|
|
3131
|
+
*
|
|
3132
|
+
* @remarks
|
|
3133
|
+
* Zip behavior for video file types:
|
|
3134
|
+
* - `auto` or `never` (default): Files are never zipped together, regardless of count.
|
|
3135
|
+
* - `always`: Files are always zipped into a single file.
|
|
3136
|
+
*/
|
|
3137
|
+
export declare type ExportVideoFileType = {
|
|
3138
|
+
type: 'gif' | 'video';
|
|
3139
|
+
zipped?: ZipBehavior;
|
|
3140
|
+
};
|
|
3141
|
+
|
|
3142
|
+
/**
|
|
3143
|
+
* @public
|
|
3144
|
+
* Image element or content to be added to the design at the end of a drag event.
|
|
3145
|
+
*
|
|
3146
|
+
* @remarks
|
|
3147
|
+
* This type is only used when the image data is from an external URL.
|
|
3148
|
+
*/
|
|
3149
|
+
export declare type ExternalImageDragConfig = CommonImageDragConfig & {
|
|
3150
|
+
/**
|
|
3151
|
+
* A function that returns a reference (ref) to an audio asset in Canva's backend.
|
|
3152
|
+
*/
|
|
3153
|
+
resolveImageRef: () => Promise<{
|
|
3154
|
+
ref: ImageRef;
|
|
3155
|
+
}>;
|
|
3156
|
+
/**
|
|
3157
|
+
* The URL of an image to display under the user's cursor during the drag and drop event.
|
|
3158
|
+
*/
|
|
3159
|
+
previewUrl: string;
|
|
3160
|
+
/**
|
|
3161
|
+
* The dimensions of the full-size image.
|
|
3162
|
+
*/
|
|
3163
|
+
fullSize?: Dimensions;
|
|
3164
|
+
};
|
|
3165
|
+
|
|
3166
|
+
/**
|
|
3167
|
+
* @public
|
|
3168
|
+
* The appearance of a path's interior.
|
|
3169
|
+
*
|
|
3170
|
+
* @remarks
|
|
3171
|
+
* The `color` and `asset` properties are mutually exclusive.
|
|
3172
|
+
*/
|
|
3173
|
+
export declare type Fill = {
|
|
3174
|
+
/**
|
|
3175
|
+
* If `true`, users can replace a fill by dropping an image or video onto it.
|
|
3176
|
+
*/
|
|
3177
|
+
dropTarget?: boolean;
|
|
3178
|
+
/**
|
|
3179
|
+
* The color of the fill as a hex code.
|
|
3180
|
+
*
|
|
3181
|
+
* @remarks
|
|
3182
|
+
* The hex code must include all six characters and be prefixed with a `#` symbol.
|
|
3183
|
+
*
|
|
3184
|
+
* @example
|
|
3185
|
+
* "#ff0099"
|
|
3186
|
+
*/
|
|
3187
|
+
color?: string;
|
|
3188
|
+
/**
|
|
3189
|
+
* An image or video to use as the fill.
|
|
3190
|
+
*/
|
|
3191
|
+
asset?: ImageFill | VideoFill;
|
|
3192
|
+
};
|
|
3193
|
+
|
|
3194
|
+
/**
|
|
3195
|
+
* @public
|
|
3196
|
+
* A reference to a font that can be used in other parts of the SDK.
|
|
3197
|
+
*/
|
|
3198
|
+
export declare type FontRef = string & {
|
|
3199
|
+
__fontRef: never;
|
|
3200
|
+
};
|
|
3201
|
+
|
|
3202
|
+
/**
|
|
3203
|
+
* @public
|
|
3204
|
+
* Font weights supported in the SDK.
|
|
3205
|
+
**/
|
|
3206
|
+
export declare type FontWeight = 'normal' | 'thin' | 'extralight' | 'light' | 'medium' | 'semibold' | 'bold' | 'ultrabold' | 'heavy';
|
|
3207
|
+
|
|
3208
|
+
/**
|
|
3209
|
+
* Allows to get the context of currently selected page.
|
|
3210
|
+
* @public
|
|
3211
|
+
* @returns Page context of currently selected page
|
|
3212
|
+
*
|
|
3213
|
+
* @example Get current page information
|
|
3214
|
+
* ```typescript
|
|
3215
|
+
* import { getCurrentPageContext } from "@canva/design";
|
|
3216
|
+
*
|
|
3217
|
+
* const pageContext = await getCurrentPageContext();
|
|
3218
|
+
* if (pageContext.dimensions) {
|
|
3219
|
+
* // Do something with the page dimensions, e.g. `pageContext.dimensions.width` and `pageContext.dimensions.height`
|
|
3220
|
+
* } else {
|
|
3221
|
+
* // This page type does not have fixed dimensions, e.g. Whiteboard or Doc
|
|
3222
|
+
* }
|
|
3223
|
+
* ```
|
|
3224
|
+
*/
|
|
3225
|
+
export declare const getCurrentPageContext: () => Promise<PageContext>;
|
|
3226
|
+
|
|
3227
|
+
/**
|
|
3228
|
+
* @deprecated
|
|
3229
|
+
* @public
|
|
3230
|
+
* Gets the default dimensions that a new page will have when it is added to a design.
|
|
3231
|
+
* It is possible for a user to resize a page without resizing the entire design, e.g. by clicking
|
|
3232
|
+
* "Expand to Whiteboard". However, there will always be a single set of default dimensions for a
|
|
3233
|
+
* design that is applied whenever a new page is created.
|
|
3234
|
+
*
|
|
3235
|
+
* Returns `undefined` if the design is unbounded (e.g. Whiteboard or Doc).
|
|
3236
|
+
*
|
|
3237
|
+
* @example Get default page dimensions
|
|
3238
|
+
* ```typescript
|
|
3239
|
+
* import { getDefaultPageDimensions } from "@canva/design";
|
|
3240
|
+
*
|
|
3241
|
+
* const dimensions = await getDefaultPageDimensions();
|
|
3242
|
+
*
|
|
3243
|
+
* if (dimensions) {
|
|
3244
|
+
* // Do something with the dimensions, e.g. `dimensions.width` and `dimensions.height`
|
|
3245
|
+
* } else {
|
|
3246
|
+
* // This design type does not have fixed dimensions, e.g. Whiteboard or Doc
|
|
3247
|
+
* }
|
|
3248
|
+
* ```
|
|
3249
|
+
*
|
|
3250
|
+
* @example Center element using page dimensions
|
|
3251
|
+
* ```typescript
|
|
3252
|
+
* import { getDefaultPageDimensions, addElementAtPoint } from "@canva/design";
|
|
3253
|
+
* import type { ImageElementAtPoint } from "@canva/design";
|
|
3254
|
+
*
|
|
3255
|
+
* const dimensions = await getDefaultPageDimensions();
|
|
3256
|
+
*
|
|
3257
|
+
* if (dimensions) {
|
|
3258
|
+
* const elementWidth = 300;
|
|
3259
|
+
* const elementHeight = 200;
|
|
3260
|
+
*
|
|
3261
|
+
* const element: ImageElementAtPoint = {
|
|
3262
|
+
* type: 'image',
|
|
3263
|
+
* dataUrl: 'data:image/png;base64,...',
|
|
3264
|
+
* altText: { text: 'Centered image', decorative: false },
|
|
3265
|
+
* top: (dimensions.height - elementHeight) / 2,
|
|
3266
|
+
* left: (dimensions.width - elementWidth) / 2,
|
|
3267
|
+
* width: elementWidth,
|
|
3268
|
+
* height: elementHeight
|
|
3269
|
+
* };
|
|
3270
|
+
*
|
|
3271
|
+
* await addElementAtPoint(element);
|
|
3272
|
+
* }
|
|
3273
|
+
* ```
|
|
3274
|
+
*/
|
|
3275
|
+
export declare const getDefaultPageDimensions: () => Promise<Dimensions | undefined>;
|
|
3276
|
+
|
|
3277
|
+
/**
|
|
3278
|
+
* @public
|
|
3279
|
+
* Retrieves information about the design.
|
|
3280
|
+
*
|
|
3281
|
+
* @example Get design metadata
|
|
3282
|
+
* ```typescript
|
|
3283
|
+
* import { getDesignMetadata } from "@canva/design";
|
|
3284
|
+
*
|
|
3285
|
+
* const metadata = await getDesignMetadata();
|
|
3286
|
+
*
|
|
3287
|
+
* const { title, defaultPageDimensions, pageMetadata, durationInSeconds } = metadata;
|
|
3288
|
+
* ```
|
|
3289
|
+
*/
|
|
3290
|
+
export declare const getDesignMetadata: () => Promise<DesignMetadata>;
|
|
3291
|
+
|
|
3292
|
+
/**
|
|
3293
|
+
* @public
|
|
3294
|
+
* Retrieves a signed JWT that contains the Design ID, App ID and User ID.
|
|
3295
|
+
*
|
|
3296
|
+
* @example Get design token
|
|
3297
|
+
* ```typescript
|
|
3298
|
+
* import { getDesignToken } from "@canva/design";
|
|
3299
|
+
*
|
|
3300
|
+
* const { token } = await getDesignToken();
|
|
3301
|
+
* ```
|
|
3302
|
+
*
|
|
3303
|
+
* @example Verify token with backend service
|
|
3304
|
+
* ```typescript
|
|
3305
|
+
* import { getDesignToken } from "@canva/design";
|
|
3306
|
+
*
|
|
3307
|
+
* const { token } = await getDesignToken();
|
|
3308
|
+
*
|
|
3309
|
+
* const verifyResponse = await fetch('https://your-backend.com/verify', {
|
|
3310
|
+
* method: 'POST',
|
|
3311
|
+
* headers: {
|
|
3312
|
+
* 'Content-Type': 'application/json'
|
|
3313
|
+
* },
|
|
3314
|
+
* body: JSON.stringify({ token })
|
|
3315
|
+
* });
|
|
3316
|
+
*
|
|
3317
|
+
* const json = await verifyResponse.json();
|
|
3318
|
+
* const { designId, appId, userId } = json;
|
|
3319
|
+
* ```
|
|
3320
|
+
*/
|
|
3321
|
+
export declare const getDesignToken: () => Promise<DesignToken>;
|
|
3322
|
+
|
|
3323
|
+
/**
|
|
3324
|
+
* @public
|
|
3325
|
+
* An element that's natively supported by the Canva editor, can exist within a group, and has positional properties.
|
|
3326
|
+
*/
|
|
3327
|
+
export declare type GroupContentAtPoint = Exclude<ElementAtPoint, GroupElementAtPoint>;
|
|
3328
|
+
|
|
3329
|
+
/**
|
|
3330
|
+
* @public
|
|
3331
|
+
* An element that contains two or more elements.
|
|
3332
|
+
*/
|
|
3333
|
+
export declare type GroupElement = {
|
|
3334
|
+
/**
|
|
3335
|
+
* The type of element.
|
|
3336
|
+
*/
|
|
3337
|
+
type: 'group';
|
|
3338
|
+
/**
|
|
3339
|
+
* The elements to render within the group.
|
|
3340
|
+
*
|
|
3341
|
+
* @remarks
|
|
3342
|
+
* - Each element within a group must have dimensions and a position.
|
|
3343
|
+
* - The dimensions and positions are relative to the dimensions and positions of the group.
|
|
3344
|
+
*/
|
|
3345
|
+
children: GroupContentAtPoint[];
|
|
3346
|
+
};
|
|
3347
|
+
|
|
3348
|
+
/**
|
|
3349
|
+
* @public
|
|
3350
|
+
* An element that contains two or more elements and has positional properties.
|
|
3351
|
+
*/
|
|
3352
|
+
export declare type GroupElementAtPoint = GroupElement & Point & (WidthAndHeight | Width | Height);
|
|
3353
|
+
|
|
3354
|
+
/**
|
|
3355
|
+
* A set of dimensions with an auto-calculated width.
|
|
3356
|
+
*/
|
|
3357
|
+
declare type Height = {
|
|
3358
|
+
/**
|
|
3359
|
+
* Indicates that the width should be auto-calculated.
|
|
3360
|
+
*/
|
|
3361
|
+
width: 'auto';
|
|
3362
|
+
/**
|
|
3363
|
+
* A height, in pixels.
|
|
3364
|
+
*
|
|
3365
|
+
* @remarks
|
|
3366
|
+
* - The pixels are relative to their container.
|
|
3367
|
+
* - Minimum: 0
|
|
3368
|
+
* - Maximum: 32767
|
|
3369
|
+
*/
|
|
3370
|
+
height: number;
|
|
3371
|
+
};
|
|
3372
|
+
|
|
3373
|
+
/**
|
|
3374
|
+
* @public
|
|
3375
|
+
* Image element or content to be added to the design at the end of a drag event.
|
|
3376
|
+
*/
|
|
3377
|
+
export declare type ImageDragConfig = ExternalImageDragConfig;
|
|
3378
|
+
|
|
3379
|
+
/**
|
|
3380
|
+
* @public
|
|
3381
|
+
* Image element or content to be added to the design at the end of a drag event.
|
|
3382
|
+
*/
|
|
3383
|
+
export declare type ImageDragConfigForElement<E extends Element> = E extends HTMLImageElement ? Partial<ImageDragConfig> & Pick<ImageDragConfig, 'type'> : ImageDragConfig;
|
|
3384
|
+
|
|
3385
|
+
/**
|
|
3386
|
+
* @public
|
|
3387
|
+
* An element that renders image content.
|
|
3388
|
+
*/
|
|
3389
|
+
export declare type ImageElement = {
|
|
3390
|
+
/**
|
|
3391
|
+
* The type of element.
|
|
3392
|
+
*/
|
|
3393
|
+
type: 'image';
|
|
3394
|
+
/**
|
|
3395
|
+
* A description of the image content.
|
|
3396
|
+
*
|
|
3397
|
+
* @remarks
|
|
3398
|
+
* Use `undefined` for content with no description.
|
|
3399
|
+
*/
|
|
3400
|
+
altText: AltText | undefined;
|
|
3401
|
+
} & ({
|
|
3402
|
+
/**
|
|
3403
|
+
* A data URL that contains the image data.
|
|
3404
|
+
*/
|
|
3405
|
+
dataUrl: string;
|
|
3406
|
+
/**
|
|
3407
|
+
* A unique identifier that points to an image asset in Canva's backend.
|
|
3408
|
+
*/
|
|
3409
|
+
ref?: never;
|
|
3410
|
+
|
|
3411
|
+
} | {
|
|
3412
|
+
/**
|
|
3413
|
+
* A data URL that contains the image data.
|
|
3414
|
+
*/
|
|
3415
|
+
dataUrl?: never;
|
|
3416
|
+
/**
|
|
3417
|
+
* A unique identifier that points to an image asset in Canva's backend.
|
|
3418
|
+
*/
|
|
3419
|
+
ref: ImageRef;
|
|
3420
|
+
});
|
|
3421
|
+
|
|
3422
|
+
/**
|
|
3423
|
+
* @public
|
|
3424
|
+
* An element that renders image content and has positional properties.
|
|
3425
|
+
*/
|
|
3426
|
+
export declare type ImageElementAtPoint = ImageElement & Point & (WidthAndHeight | Width | Height);
|
|
3427
|
+
|
|
3428
|
+
/**
|
|
3429
|
+
* @public
|
|
3430
|
+
* An image asset that fills a path's interior.
|
|
3431
|
+
*/
|
|
3432
|
+
export declare type ImageFill = {
|
|
3433
|
+
/**
|
|
3434
|
+
* The type of fill.
|
|
3435
|
+
*/
|
|
3436
|
+
type: 'image';
|
|
3437
|
+
/**
|
|
3438
|
+
* A unique identifier that points to an image asset in Canva's backend.
|
|
3439
|
+
*/
|
|
3440
|
+
ref: ImageRef;
|
|
3441
|
+
/**
|
|
3442
|
+
* A description of the image content.
|
|
3443
|
+
*
|
|
3444
|
+
* @remarks
|
|
3445
|
+
* Use `undefined` for content with no description.
|
|
3446
|
+
*/
|
|
3447
|
+
altText?: AltText;
|
|
3448
|
+
};
|
|
3449
|
+
|
|
3450
|
+
/**
|
|
3451
|
+
* @public
|
|
3452
|
+
* A unique identifier that references an image asset in Canva's backend.
|
|
3453
|
+
*/
|
|
3454
|
+
export declare type ImageRef = string & {
|
|
3455
|
+
__imageRef: never;
|
|
3456
|
+
};
|
|
3457
|
+
|
|
3458
|
+
/**
|
|
3459
|
+
* @public
|
|
3460
|
+
* @param appElementConfig - Configuration for an AppElementClient
|
|
3461
|
+
*
|
|
3462
|
+
* @example Initialize app element client
|
|
3463
|
+
* ```typescript
|
|
3464
|
+
* import { initAppElement } from "@canva/design";
|
|
3465
|
+
*
|
|
3466
|
+
* const appElement = initAppElement<{ content: string }>({
|
|
3467
|
+
* render: (data) => {
|
|
3468
|
+
* return [{
|
|
3469
|
+
* type: 'text',
|
|
3470
|
+
* children: [data.content],
|
|
3471
|
+
* top: 100,
|
|
3472
|
+
* left: 100,
|
|
3473
|
+
* width: 200
|
|
3474
|
+
* }];
|
|
3475
|
+
* }
|
|
3476
|
+
* });
|
|
3477
|
+
* ```
|
|
3478
|
+
*
|
|
3479
|
+
* @example Initialize V2 app element client
|
|
3480
|
+
* ```typescript
|
|
3481
|
+
* import { initAppElement } from "@canva/design";
|
|
3482
|
+
*
|
|
3483
|
+
* const appElement = initAppElement<{ content: string }>({
|
|
3484
|
+
* render: (data) => {
|
|
3485
|
+
* return [{
|
|
3486
|
+
* type: 'text',
|
|
3487
|
+
* children: [data.content],
|
|
3488
|
+
* top: 100,
|
|
3489
|
+
* left: 100,
|
|
3490
|
+
* width: 200
|
|
3491
|
+
* }];
|
|
3492
|
+
* }
|
|
3493
|
+
* });
|
|
3494
|
+
* ```
|
|
3495
|
+
*/
|
|
3496
|
+
export declare const initAppElement: <A extends AppElementData>(appElementConfig: AppElementClientConfiguration<A>) => AppElementClient<A>;
|
|
3497
|
+
|
|
3498
|
+
/**
|
|
3499
|
+
* @public
|
|
3500
|
+
* Options for formatting inline richtext.
|
|
3501
|
+
*/
|
|
3502
|
+
export declare type InlineFormatting = {
|
|
3503
|
+
/**
|
|
3504
|
+
* The color of the text as a hex code.
|
|
3505
|
+
*
|
|
3506
|
+
* @remarks
|
|
3507
|
+
* The hex code must include all six characters and be prefixed with a `#` symbol.
|
|
3508
|
+
*
|
|
3509
|
+
* @example
|
|
3510
|
+
* "#ff0099"
|
|
3511
|
+
*/
|
|
3512
|
+
color?: string;
|
|
3513
|
+
/**
|
|
3514
|
+
* The weight (thickness) of the font.
|
|
3515
|
+
*
|
|
3516
|
+
* @remarks
|
|
3517
|
+
* The available font weights depend on the font.
|
|
3518
|
+
*
|
|
3519
|
+
* @defaultValue "normal"
|
|
3520
|
+
*/
|
|
3521
|
+
fontWeight?: FontWeight;
|
|
3522
|
+
/**
|
|
3523
|
+
* The style of the font.
|
|
3524
|
+
* @defaultValue "normal"
|
|
3525
|
+
*/
|
|
3526
|
+
fontStyle?: 'normal' | 'italic';
|
|
3527
|
+
/**
|
|
3528
|
+
* The decoration of the text.
|
|
3529
|
+
* @defaultValue "none"
|
|
3530
|
+
*/
|
|
3531
|
+
decoration?: 'none' | 'underline';
|
|
3532
|
+
/**
|
|
3533
|
+
* The strikethrough of the text.
|
|
3534
|
+
* @defaultValue "none"
|
|
3535
|
+
*/
|
|
3536
|
+
strikethrough?: 'none' | 'strikethrough';
|
|
3537
|
+
/**
|
|
3538
|
+
* An external URL that the text links to.
|
|
3539
|
+
*/
|
|
3540
|
+
link?: string;
|
|
3541
|
+
};
|
|
3542
|
+
|
|
3543
|
+
/**
|
|
3544
|
+
* @public
|
|
3545
|
+
* Options for configuring the bulk create panel.
|
|
3546
|
+
*/
|
|
3547
|
+
export declare type LaunchBulkCreateOpts = {
|
|
3548
|
+
/**
|
|
3549
|
+
* The option to make sure the data connector intent of the current app will be triggered.
|
|
3550
|
+
*/
|
|
3551
|
+
withDataConnector: 'self';
|
|
3552
|
+
};
|
|
3553
|
+
|
|
3554
|
+
/**
|
|
3555
|
+
* @public
|
|
3556
|
+
* Options for configuring the publish menu.
|
|
3557
|
+
*/
|
|
3558
|
+
export declare type LaunchPublishOpts = {
|
|
3559
|
+
/**
|
|
3560
|
+
* The option to make sure the content publisher intent of the current app will be triggered.
|
|
3561
|
+
*/
|
|
3562
|
+
withContentPublisher: 'self';
|
|
3563
|
+
};
|
|
3564
|
+
|
|
3565
|
+
/**
|
|
3566
|
+
* @deprecated The type has been superseded by `DesignElement`.
|
|
3567
|
+
* @public
|
|
3568
|
+
* An element that's natively supported by the Canva editor.
|
|
3569
|
+
*/
|
|
3570
|
+
export declare type NativeElement = NativeImageElement | NativeVideoElement | NativeEmbedElement | NativeTextElement | NativeShapeElement | NativeGroupElement;
|
|
3571
|
+
|
|
3572
|
+
/**
|
|
3573
|
+
* @deprecated
|
|
3574
|
+
* @public
|
|
3575
|
+
* The types of elements an app can add to a user's design.
|
|
3576
|
+
*/
|
|
3577
|
+
export declare type NativeElementType = 'image' | 'embed' | 'text' | 'shape' | 'video';
|
|
3578
|
+
|
|
3579
|
+
/**
|
|
3580
|
+
* @deprecated The type has been superseded by `ElementAtPoint`.
|
|
3581
|
+
* @public
|
|
3582
|
+
* An element that's natively supported by the Canva editor and has positional properties.
|
|
3583
|
+
*/
|
|
3584
|
+
export declare type NativeElementWithBox = NativeImageElementWithBox | NativeVideoElementWithBox | NativeEmbedElementWithBox | NativeTextElementWithBox | NativeShapeElementWithBox | NativeGroupElementWithBox;
|
|
3585
|
+
|
|
3586
|
+
/**
|
|
3587
|
+
* @deprecated The type has been superseded by `EmbedElement`.
|
|
3588
|
+
* @public
|
|
3589
|
+
* An element that renders rich media, such as a YouTube video.
|
|
3590
|
+
*/
|
|
3591
|
+
export declare type NativeEmbedElement = EmbedElement;
|
|
3592
|
+
|
|
3593
|
+
/**
|
|
3594
|
+
* @deprecated The type has been superseded by `EmbedElementAtPoint`.
|
|
3595
|
+
* @public
|
|
3596
|
+
* An element that renders rich media, such as a YouTube video, and has positional properties.
|
|
3597
|
+
*/
|
|
3598
|
+
export declare type NativeEmbedElementWithBox = EmbedElementAtPoint;
|
|
3599
|
+
|
|
3600
|
+
/**
|
|
3601
|
+
* @deprecated The type has been superseded by `GroupElement`.
|
|
3602
|
+
* @public
|
|
3603
|
+
* An element that contains two or more elements.
|
|
3604
|
+
*/
|
|
3605
|
+
export declare type NativeGroupElement = GroupElement;
|
|
3606
|
+
|
|
3607
|
+
/**
|
|
3608
|
+
* @deprecated The type has been superseded by `GroupElementAtPoint`.
|
|
3609
|
+
* @public
|
|
3610
|
+
* An element that contains two or more elements and has positional properties.
|
|
3611
|
+
*/
|
|
3612
|
+
export declare type NativeGroupElementWithBox = GroupElementAtPoint;
|
|
3613
|
+
|
|
3614
|
+
/**
|
|
3615
|
+
* @deprecated The type has been superseded by `ImageElement`.
|
|
3616
|
+
* @public
|
|
3617
|
+
* An element that renders image content.
|
|
3618
|
+
*/
|
|
3619
|
+
export declare type NativeImageElement = ImageElement;
|
|
3620
|
+
|
|
3621
|
+
/**
|
|
3622
|
+
* @deprecated The type has been superseded by `ImageElementAtPoint`.
|
|
3623
|
+
* @public
|
|
3624
|
+
* An element that renders image content and has positional properties.
|
|
3625
|
+
*/
|
|
3626
|
+
export declare type NativeImageElementWithBox = ImageElementAtPoint;
|
|
3627
|
+
|
|
3628
|
+
/**
|
|
3629
|
+
* @deprecated The type has been superseded by `ShapeElement`.
|
|
3630
|
+
* @public
|
|
3631
|
+
* An element that renders a vector shape.
|
|
3632
|
+
*/
|
|
3633
|
+
export declare type NativeShapeElement = ShapeElement;
|
|
3634
|
+
|
|
3635
|
+
/**
|
|
3636
|
+
* @deprecated The type has been superseded by `ShapeElementAtPoint`.
|
|
3637
|
+
* @public
|
|
3638
|
+
* An element that renders a vector shape and has positional properties.
|
|
3639
|
+
*/
|
|
3640
|
+
export declare type NativeShapeElementWithBox = ShapeElementAtPoint;
|
|
3641
|
+
|
|
3642
|
+
/**
|
|
3643
|
+
* @deprecated The type has been superseded by `GroupContentAtPoint`.
|
|
3644
|
+
* @public
|
|
3645
|
+
* An element that's natively supported by the Canva editor, can exist within a group, and has positional properties.
|
|
3646
|
+
*/
|
|
3647
|
+
export declare type NativeSimpleElementWithBox = GroupContentAtPoint;
|
|
3648
|
+
|
|
3649
|
+
/**
|
|
3650
|
+
* @deprecated The type has been superseded by `TextElement`.
|
|
3651
|
+
* @public
|
|
3652
|
+
* An element that renders text content.
|
|
3653
|
+
*/
|
|
3654
|
+
export declare type NativeTextElement = TextElement;
|
|
3655
|
+
|
|
3656
|
+
/**
|
|
3657
|
+
* @deprecated The type has been superseded by `TextElementAtPoint`.
|
|
3658
|
+
* @public
|
|
3659
|
+
* An element that renders text content and has positional properties.
|
|
3660
|
+
*/
|
|
3661
|
+
export declare type NativeTextElementWithBox = TextElementAtPoint;
|
|
3662
|
+
|
|
3663
|
+
/**
|
|
3664
|
+
* @deprecated The type has been superseded by `VideoElement`.
|
|
3665
|
+
* @public
|
|
3666
|
+
* An element that renders video content.
|
|
3667
|
+
*/
|
|
3668
|
+
export declare type NativeVideoElement = VideoElement;
|
|
3669
|
+
|
|
3670
|
+
/**
|
|
3671
|
+
* @deprecated The type has been superseded by `VideoElementAtPoint`.
|
|
3672
|
+
* @public
|
|
3673
|
+
* An element that renders video content and has positional properties.
|
|
3674
|
+
*/
|
|
3675
|
+
export declare type NativeVideoElementWithBox = VideoElementAtPoint;
|
|
3676
|
+
|
|
3677
|
+
/**
|
|
3678
|
+
* An object primitive data type that can be used in app element data.
|
|
3679
|
+
*/
|
|
3680
|
+
declare type ObjectPrimitive = Boolean | String;
|
|
3681
|
+
|
|
3682
|
+
/**
|
|
3683
|
+
* @public
|
|
3684
|
+
*
|
|
3685
|
+
* Reads a specified part of the user's design and returns all elements in that part.
|
|
3686
|
+
*
|
|
3687
|
+
* @param options - Options for configuring how the design is read.
|
|
3688
|
+
* @param callback - A callback for operating on the design.
|
|
3689
|
+
*/
|
|
3690
|
+
export declare const openDesign: (options: DesignOpenOptions, callback: DesignOpenCallback) => Promise<void>;
|
|
3691
|
+
|
|
3692
|
+
/**
|
|
3693
|
+
* @public
|
|
3694
|
+
* An alias for the DesignOverlay interface, providing access to design overlay related functionality
|
|
3695
|
+
*/
|
|
3696
|
+
export declare const overlay: DesignOverlay;
|
|
3697
|
+
|
|
3698
|
+
/**
|
|
3699
|
+
* @public
|
|
3700
|
+
* Information about whether or not an overlay can be opened for the specified target.
|
|
3701
|
+
*/
|
|
3702
|
+
export declare type OverlayOpenableEvent<Target extends OverlayTarget> = {
|
|
3703
|
+
/**
|
|
3704
|
+
* Information about whether or not an overlay can be opened or not for a selected image.
|
|
3705
|
+
*/
|
|
3706
|
+
['image_selection']: OverlayUnopenableEvent | {
|
|
3707
|
+
/**
|
|
3708
|
+
* Indicates that the overlay can be opened for the selected image.
|
|
3709
|
+
*/
|
|
3710
|
+
canOpen: true;
|
|
3711
|
+
/**
|
|
3712
|
+
* Opens an overlay for the selected image.
|
|
3713
|
+
* @param opts - Options for launching the process associated with the overlay.
|
|
3714
|
+
*/
|
|
3715
|
+
readonly open: (options: {
|
|
3716
|
+
/**
|
|
3717
|
+
* Parameters to pass to the overlay when it opens.
|
|
3718
|
+
*
|
|
3719
|
+
* @remarks
|
|
3720
|
+
* This can be any type of structured data.
|
|
3721
|
+
*/
|
|
3722
|
+
launchParameters?: unknown;
|
|
3723
|
+
}) => Promise<AppProcessId>;
|
|
3724
|
+
};
|
|
3725
|
+
}[Target];
|
|
3726
|
+
|
|
3727
|
+
/**
|
|
3728
|
+
* @public
|
|
3729
|
+
* An entity that an overlay can be opened for.
|
|
3730
|
+
*/
|
|
3731
|
+
export declare type OverlayTarget = 'image_selection';
|
|
3732
|
+
|
|
3733
|
+
/**
|
|
3734
|
+
* @public
|
|
3735
|
+
* Information about an overlay that can't be opened for the specified target.
|
|
3736
|
+
*/
|
|
3737
|
+
declare type OverlayUnopenableEvent = {
|
|
3738
|
+
/**
|
|
3739
|
+
* Indicates that the overlay can't be opened for the specified target.
|
|
3740
|
+
*/
|
|
3741
|
+
canOpen: false;
|
|
3742
|
+
/**
|
|
3743
|
+
* Indicates the reason the overlay can't be opened for the specified target.
|
|
3744
|
+
*/
|
|
3745
|
+
reason: string;
|
|
3746
|
+
};
|
|
3747
|
+
|
|
3748
|
+
/**
|
|
3749
|
+
* @public
|
|
3750
|
+
* The appearance of a page's background.
|
|
3751
|
+
*/
|
|
3752
|
+
export declare type PageBackgroundFill = Pick<Fill, 'asset' | 'color'>;
|
|
3753
|
+
|
|
3754
|
+
/**
|
|
3755
|
+
* @public
|
|
3756
|
+
* Information about a page.
|
|
3757
|
+
*/
|
|
3758
|
+
export declare type PageContext = {
|
|
3759
|
+
/**
|
|
3760
|
+
* The dimensions of the page, in pixels.
|
|
3761
|
+
*
|
|
3762
|
+
* @remarks
|
|
3763
|
+
* This may be `undefined` because some types of pages don't have dimensions, such as whiteboards.
|
|
3764
|
+
*/
|
|
3765
|
+
dimensions: PageDimensions | undefined;
|
|
3766
|
+
};
|
|
3767
|
+
|
|
3768
|
+
/**
|
|
3769
|
+
* @public
|
|
3770
|
+
* A set of page dimensions, in pixels.
|
|
3771
|
+
*/
|
|
3772
|
+
export declare type PageDimensions = {
|
|
3773
|
+
/**
|
|
3774
|
+
* The width of the page, in pixels.
|
|
3775
|
+
*/
|
|
3776
|
+
width: number;
|
|
3777
|
+
/**
|
|
3778
|
+
* The height of the page, in pixels.
|
|
3779
|
+
*/
|
|
3780
|
+
height: number;
|
|
3781
|
+
};
|
|
3782
|
+
|
|
3783
|
+
/**
|
|
3784
|
+
* @public
|
|
3785
|
+
* Information about a page.
|
|
3786
|
+
*/
|
|
3787
|
+
export declare type PageMetadata = {
|
|
3788
|
+
|
|
3789
|
+
/**
|
|
3790
|
+
*
|
|
3791
|
+
* The dimensions of the page, in pixels.
|
|
3792
|
+
*
|
|
3793
|
+
* @remarks
|
|
3794
|
+
* This may be `undefined` because some types of pages don't have dimensions, such as whiteboards.
|
|
3795
|
+
*/
|
|
3796
|
+
dimensions?: PageDimensions;
|
|
3797
|
+
};
|
|
3798
|
+
|
|
3799
|
+
/**
|
|
3800
|
+
* @public
|
|
3801
|
+
* The outline of a path.
|
|
3802
|
+
*/
|
|
3803
|
+
export declare type PathStroke = {
|
|
3804
|
+
/**
|
|
3805
|
+
* The weight (thickness) of the stroke.
|
|
3806
|
+
*
|
|
3807
|
+
* @remarks
|
|
3808
|
+
* - Minimum: 0
|
|
3809
|
+
* - Maximum: 100
|
|
3810
|
+
*/
|
|
3811
|
+
weight: number;
|
|
3812
|
+
/**
|
|
3813
|
+
* The color of the stroke as a hex code.
|
|
3814
|
+
*
|
|
3815
|
+
* @remarks
|
|
3816
|
+
* The hex code must include all six characters and be prefixed with a `#` symbol.
|
|
3817
|
+
*
|
|
3818
|
+
* @example
|
|
3819
|
+
* "#ff0099"
|
|
3820
|
+
*/
|
|
3821
|
+
color: string;
|
|
3822
|
+
/**
|
|
3823
|
+
* The alignment of the stroke.
|
|
3824
|
+
*/
|
|
3825
|
+
strokeAlign: 'inset';
|
|
3826
|
+
};
|
|
3827
|
+
|
|
3828
|
+
/**
|
|
3829
|
+
* @public
|
|
3830
|
+
* A position, set of dimensions, and rotation.
|
|
3831
|
+
*/
|
|
3832
|
+
export declare type Placement = Point & (WidthAndHeight | Width | Height);
|
|
3833
|
+
|
|
3834
|
+
/**
|
|
3835
|
+
* A position and rotation.
|
|
3836
|
+
*/
|
|
3837
|
+
declare type Point = {
|
|
3838
|
+
/**
|
|
3839
|
+
* The distance from the top edge of the container, in pixels.
|
|
3840
|
+
*
|
|
3841
|
+
* @remarks
|
|
3842
|
+
* - The pixels are relative to their container.
|
|
3843
|
+
* - Minimum: -32768
|
|
3844
|
+
* - Maximum: 32767
|
|
3845
|
+
*/
|
|
3846
|
+
top: number;
|
|
3847
|
+
/**
|
|
3848
|
+
* The distance from the left edge of the container, in pixels.
|
|
3849
|
+
*
|
|
3850
|
+
* @remarks
|
|
3851
|
+
* - The pixels are relative to their container.
|
|
3852
|
+
* - Minimum: -32768
|
|
3853
|
+
* - Maximum: 32767
|
|
3854
|
+
*/
|
|
3855
|
+
left: number;
|
|
3856
|
+
/**
|
|
3857
|
+
* A rotation, in degrees.
|
|
3858
|
+
*
|
|
3859
|
+
* @remarks
|
|
3860
|
+
* - Minimum: -180
|
|
3861
|
+
* - Maximum: 180
|
|
3862
|
+
*/
|
|
3863
|
+
rotation?: number;
|
|
3864
|
+
};
|
|
3865
|
+
|
|
3866
|
+
/**
|
|
3867
|
+
* A primitive data type that can be used in app element data.
|
|
3868
|
+
*
|
|
3869
|
+
* @remarks
|
|
3870
|
+
* All primitive data types are supported except for symbols and bigints.
|
|
3871
|
+
*/
|
|
3872
|
+
declare type Primitive = undefined | null | number | boolean | string;
|
|
3873
|
+
|
|
3874
|
+
/**
|
|
3875
|
+
* @public
|
|
3876
|
+
* An alias for the PublishLauncher interface, providing access to design publishing related functionality
|
|
3877
|
+
*/
|
|
3878
|
+
export declare const publish: PublishLauncher;
|
|
3879
|
+
|
|
3880
|
+
/**
|
|
3881
|
+
* @public
|
|
3882
|
+
* Provides methods for launching the publish menu
|
|
3883
|
+
*/
|
|
3884
|
+
export declare type PublishLauncher = {
|
|
3885
|
+
/**
|
|
3886
|
+
* @public
|
|
3887
|
+
* Launches the design publish with the content publisher intent.
|
|
3888
|
+
* @param opts - Options for configuring the publish menu.
|
|
3889
|
+
* @throws unsupported_surface code if not invoked by the design editor intent.
|
|
3890
|
+
*
|
|
3891
|
+
* @example Launch the content publisher with the same app
|
|
3892
|
+
* ```typescript
|
|
3893
|
+
* import { publish } from "@canva/design";
|
|
3894
|
+
* import { features } from "@canva/platform";
|
|
3895
|
+
*
|
|
3896
|
+
* if (features.isSupported(publish.launch)) {
|
|
3897
|
+
* await publish.launch({ withContentPublisher: 'self' });
|
|
3898
|
+
* }
|
|
3899
|
+
* ```
|
|
3900
|
+
*/
|
|
3901
|
+
launch(opts: LaunchPublishOpts): Promise<void>;
|
|
3902
|
+
};
|
|
3903
|
+
|
|
3904
|
+
/**
|
|
3905
|
+
* @public
|
|
3906
|
+
* Exports the user's design as one or more static files.
|
|
3907
|
+
* @param request - The request object containing configurations of the design export.
|
|
3908
|
+
*/
|
|
3909
|
+
export declare const requestExport: (request: ExportRequest) => Promise<ExportResponse>;
|
|
3910
|
+
|
|
3911
|
+
/**
|
|
3912
|
+
* @public
|
|
3913
|
+
* Provides methods for interacting with a range of formatted text.
|
|
3914
|
+
*/
|
|
3915
|
+
export declare interface RichtextContentRange extends RichtextRange {
|
|
3916
|
+
/**
|
|
3917
|
+
* Indicates whether the object containing this richtext range has been deleted.
|
|
3918
|
+
*/
|
|
3919
|
+
readonly deleted: boolean;
|
|
3920
|
+
}
|
|
3921
|
+
|
|
3922
|
+
/**
|
|
3923
|
+
* @public
|
|
3924
|
+
* A callback for reading and updating the requested design content.
|
|
3925
|
+
* @param session - The result of reading the content in the design.
|
|
3926
|
+
*
|
|
3927
|
+
* @example Read and update richtext content
|
|
3928
|
+
* ```typescript
|
|
3929
|
+
* import { editContent } from "@canva/design";
|
|
3930
|
+
*
|
|
3931
|
+
* await editContent(
|
|
3932
|
+
* { contentType: 'richtext', target: 'current_page' },
|
|
3933
|
+
* async (session) => {
|
|
3934
|
+
* // Read the content
|
|
3935
|
+
* const contents = session.contents;
|
|
3936
|
+
*
|
|
3937
|
+
* if (contents.length > 0) {
|
|
3938
|
+
* const range = contents[0];
|
|
3939
|
+
*
|
|
3940
|
+
* // Modify the content (e.g., adding text)
|
|
3941
|
+
* range.appendText("\nAppended text from app");
|
|
3942
|
+
*
|
|
3943
|
+
* // Sync changes back to the design
|
|
3944
|
+
* await session.sync();
|
|
3945
|
+
* }
|
|
3946
|
+
* }
|
|
3947
|
+
* );
|
|
3948
|
+
* ```
|
|
3949
|
+
*
|
|
3950
|
+
* @example Format all richtext content in the design
|
|
3951
|
+
* ```typescript
|
|
3952
|
+
* import { editContent } from "@canva/design";
|
|
3953
|
+
*
|
|
3954
|
+
* await editContent(
|
|
3955
|
+
* { contentType: 'richtext', target: 'current_page' },
|
|
3956
|
+
* async (session) => {
|
|
3957
|
+
* // Process each richtext range in the content
|
|
3958
|
+
* for (const range of session.contents) {
|
|
3959
|
+
* // Skip if the content has been deleted
|
|
3960
|
+
* if (range.deleted) continue;
|
|
3961
|
+
*
|
|
3962
|
+
* // Get the text content
|
|
3963
|
+
* const text = range.readPlaintext();
|
|
3964
|
+
* if (text.length === 0) continue;
|
|
3965
|
+
*
|
|
3966
|
+
* // Apply consistent formatting
|
|
3967
|
+
* range.formatParagraph(
|
|
3968
|
+
* { index: 0, length: text.length },
|
|
3969
|
+
* {
|
|
3970
|
+
* fontRef: 'YOUR_FONT_REF',
|
|
3971
|
+
* fontSize: 16,
|
|
3972
|
+
* textAlign: 'start'
|
|
3973
|
+
* }
|
|
3974
|
+
* );
|
|
3975
|
+
* }
|
|
3976
|
+
*
|
|
3977
|
+
* // Sync all changes back to the design
|
|
3978
|
+
* await session.sync();
|
|
3979
|
+
* }
|
|
3980
|
+
* );
|
|
3981
|
+
* ```
|
|
3982
|
+
*
|
|
3983
|
+
* @example Modify content without saving changes
|
|
3984
|
+
* ```typescript
|
|
3985
|
+
* import { editContent } from "@canva/design";
|
|
3986
|
+
*
|
|
3987
|
+
* await editContent(
|
|
3988
|
+
* { contentType: 'richtext', target: 'current_page' },
|
|
3989
|
+
* async (session) => {
|
|
3990
|
+
* // Read and analyze the content without making changes
|
|
3991
|
+
* for (const range of session.contents) {
|
|
3992
|
+
* const text = range.readPlaintext();
|
|
3993
|
+
* // Do something with the content preview, e.g. `text.substring(0, 50)`
|
|
3994
|
+
*
|
|
3995
|
+
* // No call to session.sync() means no changes are saved
|
|
3996
|
+
* }
|
|
3997
|
+
*
|
|
3998
|
+
* // Since we're not calling sync(), no changes will be made to the design
|
|
3999
|
+
* }
|
|
4000
|
+
* );
|
|
4001
|
+
* ```
|
|
4002
|
+
*/
|
|
4003
|
+
export declare interface RichtextContentSession {
|
|
4004
|
+
/**
|
|
4005
|
+
* Richtext content in the design.
|
|
4006
|
+
*/
|
|
4007
|
+
readonly contents: readonly RichtextContentRange[];
|
|
4008
|
+
/**
|
|
4009
|
+
* Saves any changes made during the session while keeping the transaction open.
|
|
4010
|
+
*
|
|
4011
|
+
* @remarks
|
|
4012
|
+
* - Any changes in the session are only reflected in the design after this method is called.
|
|
4013
|
+
* - Once this method is called, further changes in the session can still be made.
|
|
4014
|
+
*
|
|
4015
|
+
* @example Sync changes after modifying content
|
|
4016
|
+
* ```typescript
|
|
4017
|
+
* import { editContent } from "@canva/design";
|
|
4018
|
+
*
|
|
4019
|
+
* await editContent(
|
|
4020
|
+
* { contentType: 'richtext', target: 'current_page' },
|
|
4021
|
+
* async (session) => {
|
|
4022
|
+
* if (session.contents.length > 0) {
|
|
4023
|
+
* const range = session.contents[0];
|
|
4024
|
+
*
|
|
4025
|
+
* // Make modifications to the content
|
|
4026
|
+
* range.appendText(" - Modified by app");
|
|
4027
|
+
*
|
|
4028
|
+
* try {
|
|
4029
|
+
* // Save changes back to the design
|
|
4030
|
+
* await session.sync();
|
|
4031
|
+
* } catch (error) {
|
|
4032
|
+
* console.error('Failed to sync changes:', error);
|
|
4033
|
+
* }
|
|
4034
|
+
* }
|
|
4035
|
+
* }
|
|
4036
|
+
* );
|
|
4037
|
+
* ```
|
|
4038
|
+
*/
|
|
4039
|
+
sync(): Promise<void>;
|
|
4040
|
+
}
|
|
4041
|
+
|
|
4042
|
+
/**
|
|
4043
|
+
* @public
|
|
4044
|
+
* An element that renders richtext content.
|
|
4045
|
+
*/
|
|
4046
|
+
export declare type RichtextElement = {
|
|
4047
|
+
/**
|
|
4048
|
+
* The type of element.
|
|
4049
|
+
*/
|
|
4050
|
+
type: 'richtext';
|
|
4051
|
+
/**
|
|
4052
|
+
* The richtext content.
|
|
4053
|
+
*/
|
|
4054
|
+
range: RichtextRange;
|
|
4055
|
+
};
|
|
4056
|
+
|
|
4057
|
+
/**
|
|
4058
|
+
* @public
|
|
4059
|
+
* An element that renders richtext content.
|
|
4060
|
+
*
|
|
4061
|
+
* @remarks
|
|
4062
|
+
* This type includes properties for controlling the position and dimensions of the
|
|
4063
|
+
* element.
|
|
4064
|
+
* It will be positioned and sized relative to its parent container.
|
|
4065
|
+
* The parent container may be an app element, or the current page.
|
|
4066
|
+
*/
|
|
4067
|
+
export declare type RichtextElementAtPoint = RichtextElement & TextBox;
|
|
4068
|
+
|
|
4069
|
+
/**
|
|
4070
|
+
* @public
|
|
4071
|
+
* Options for formatting richtext.
|
|
4072
|
+
*/
|
|
4073
|
+
export declare type RichtextFormatting = InlineFormatting & {
|
|
4074
|
+
/**
|
|
4075
|
+
* @public
|
|
4076
|
+
* A unique identifier that points to a font asset in Canva's backend.
|
|
4077
|
+
*/
|
|
4078
|
+
fontRef?: FontRef;
|
|
4079
|
+
/**
|
|
4080
|
+
* The size of the text, in pixels.
|
|
4081
|
+
*
|
|
4082
|
+
* @remarks
|
|
4083
|
+
* - In the Canva editor, this number is shown as points (pts), not pixels.
|
|
4084
|
+
* - Minimum: 1
|
|
4085
|
+
* - Maximum: 100
|
|
4086
|
+
*/
|
|
4087
|
+
fontSize?: number;
|
|
4088
|
+
/**
|
|
4089
|
+
* The alignment of the text.
|
|
4090
|
+
* @defaultValue "start"
|
|
4091
|
+
*/
|
|
4092
|
+
textAlign?: 'start' | 'center' | 'end' | 'justify';
|
|
4093
|
+
/**
|
|
4094
|
+
* The list indentation level of the paragraph.
|
|
4095
|
+
*/
|
|
4096
|
+
listLevel?: number;
|
|
4097
|
+
/**
|
|
4098
|
+
* The appearance of list item markers.
|
|
4099
|
+
*
|
|
4100
|
+
* @remarks
|
|
4101
|
+
* This property only has an effect if `listLevel` is greater than 0.
|
|
4102
|
+
*
|
|
4103
|
+
* @defaultValue "none"
|
|
4104
|
+
*/
|
|
4105
|
+
listMarker?: 'none' | 'disc' | 'circle' | 'square' | 'decimal' | 'lower-alpha' | 'lower-roman' | 'checked' | 'unchecked';
|
|
4106
|
+
};
|
|
4107
|
+
|
|
4108
|
+
/**
|
|
4109
|
+
* @public
|
|
4110
|
+
* Provides methods for interacting with a range of formatted text.
|
|
4111
|
+
*/
|
|
4112
|
+
export declare type RichtextRange = {
|
|
4113
|
+
/**
|
|
4114
|
+
* Formats all of the paragraphs that overlap the given bounds.
|
|
4115
|
+
*
|
|
4116
|
+
* @param bounds - The segment of the range on which to apply the formatting.
|
|
4117
|
+
* @param formatting - The formatting to apply to the paragraph(s).
|
|
4118
|
+
*
|
|
4119
|
+
* @remarks
|
|
4120
|
+
* - The `\n` character indicates the end of a paragraph.
|
|
4121
|
+
* - All paragraphs that overlap the provided bounds will be formatted in their entirety.
|
|
4122
|
+
*
|
|
4123
|
+
* @example Format paragraph as a heading
|
|
4124
|
+
* ```typescript
|
|
4125
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4126
|
+
*
|
|
4127
|
+
* const range = createRichtextRange();
|
|
4128
|
+
*
|
|
4129
|
+
* range.appendText("Heading Text\nRegular paragraph text.");
|
|
4130
|
+
*
|
|
4131
|
+
* // Format just the first paragraph as a heading
|
|
4132
|
+
* range.formatParagraph(
|
|
4133
|
+
* { index: 0, length: 12 }, // Only need to include part of the paragraph
|
|
4134
|
+
* {
|
|
4135
|
+
* fontSize: 24,
|
|
4136
|
+
* fontWeight: 'bold',
|
|
4137
|
+
* textAlign: 'center'
|
|
4138
|
+
* }
|
|
4139
|
+
* );
|
|
4140
|
+
* ```
|
|
4141
|
+
*
|
|
4142
|
+
* @example Create a bulleted list
|
|
4143
|
+
* ```typescript
|
|
4144
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4145
|
+
*
|
|
4146
|
+
* const range = createRichtextRange();
|
|
4147
|
+
* const text = "Item 1\nItem 2\nItem 3";
|
|
4148
|
+
* range.appendText(text);
|
|
4149
|
+
*
|
|
4150
|
+
* // Format all paragraphs as a bulleted list
|
|
4151
|
+
* range.formatParagraph(
|
|
4152
|
+
* { index: 0, length: text.length },
|
|
4153
|
+
* {
|
|
4154
|
+
* listLevel: 1,
|
|
4155
|
+
* listMarker: 'disc'
|
|
4156
|
+
* }
|
|
4157
|
+
* );
|
|
4158
|
+
* ```
|
|
4159
|
+
*/
|
|
4160
|
+
formatParagraph(bounds: Bounds, formatting: RichtextFormatting): void;
|
|
4161
|
+
/**
|
|
4162
|
+
* Formats a region of text with inline formatting properties.
|
|
4163
|
+
*
|
|
4164
|
+
* @param bounds - The segment of the range on which to apply the formatting.
|
|
4165
|
+
* @param formatting - The formatting to apply to the text.
|
|
4166
|
+
*
|
|
4167
|
+
* @example Format specific words in a paragraph
|
|
4168
|
+
* ```typescript
|
|
4169
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4170
|
+
*
|
|
4171
|
+
* const range = createRichtextRange();
|
|
4172
|
+
* range.appendText("This text contains important information.");
|
|
4173
|
+
*
|
|
4174
|
+
* // Format just the word "important"
|
|
4175
|
+
* range.formatText(
|
|
4176
|
+
* { index: 16, length: 9 },
|
|
4177
|
+
* {
|
|
4178
|
+
* fontWeight: 'bold',
|
|
4179
|
+
* color: '#FF0000'
|
|
4180
|
+
* }
|
|
4181
|
+
* );
|
|
4182
|
+
* ```
|
|
4183
|
+
*
|
|
4184
|
+
* @example Add a link to text
|
|
4185
|
+
* ```typescript
|
|
4186
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4187
|
+
*
|
|
4188
|
+
* const range = createRichtextRange();
|
|
4189
|
+
* range.appendText("Visit our website for more information.");
|
|
4190
|
+
*
|
|
4191
|
+
* // Add a link to "our website"
|
|
4192
|
+
* range.formatText(
|
|
4193
|
+
* { index: 6, length: 11 },
|
|
4194
|
+
* {
|
|
4195
|
+
* link: "https://www.example.com",
|
|
4196
|
+
* decoration: 'underline',
|
|
4197
|
+
* color: '#0066CC'
|
|
4198
|
+
* }
|
|
4199
|
+
* );
|
|
4200
|
+
* ```
|
|
4201
|
+
*/
|
|
4202
|
+
formatText(bounds: Bounds, formatting: InlineFormatting): void;
|
|
4203
|
+
/**
|
|
4204
|
+
* Appends the specified characters to the end of the range.
|
|
4205
|
+
*
|
|
4206
|
+
* @param characters - The characters to append to the richtext range.
|
|
4207
|
+
* @param formatting - Optional formatting to apply to the appended text.
|
|
4208
|
+
*
|
|
4209
|
+
* @example Append plain text
|
|
4210
|
+
* ```typescript
|
|
4211
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4212
|
+
*
|
|
4213
|
+
* const range = createRichtextRange();
|
|
4214
|
+
* range.appendText("First paragraph. ");
|
|
4215
|
+
*
|
|
4216
|
+
* // Append more text to the existing content
|
|
4217
|
+
* const result = range.appendText("This is additional text.");
|
|
4218
|
+
*
|
|
4219
|
+
* // The bounds of the newly added text are returned
|
|
4220
|
+
* // Do something with the bounds - result.bounds, e.g. { index: 17, length: 24 }
|
|
4221
|
+
* ```
|
|
4222
|
+
*
|
|
4223
|
+
* @example Append formatted text
|
|
4224
|
+
* ```typescript
|
|
4225
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4226
|
+
*
|
|
4227
|
+
* const range = createRichtextRange();
|
|
4228
|
+
* range.appendText("Normal text followed by ");
|
|
4229
|
+
*
|
|
4230
|
+
* // Append formatted text
|
|
4231
|
+
* range.appendText("bold red text", {
|
|
4232
|
+
* fontWeight: 'bold',
|
|
4233
|
+
* color: '#FF0000'
|
|
4234
|
+
* });
|
|
4235
|
+
*
|
|
4236
|
+
* // Append a new paragraph
|
|
4237
|
+
* range.appendText("\nThis is a new paragraph.");
|
|
4238
|
+
* ```
|
|
4239
|
+
*/
|
|
4240
|
+
appendText(characters: string, formatting?: InlineFormatting): {
|
|
4241
|
+
bounds: Bounds;
|
|
4242
|
+
};
|
|
4243
|
+
/**
|
|
4244
|
+
* Replaces a region of text with the specified characters.
|
|
4245
|
+
*
|
|
4246
|
+
* @param bounds - The segment of the range to replace.
|
|
4247
|
+
* @param characters - The replacement characters.
|
|
4248
|
+
* @param formatting - The formatting to apply to the replaced text.
|
|
4249
|
+
*
|
|
4250
|
+
* @example Replace text while maintaining some formatting
|
|
4251
|
+
* ```typescript
|
|
4252
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4253
|
+
*
|
|
4254
|
+
* const range = createRichtextRange();
|
|
4255
|
+
* range.appendText("This text needs correction.");
|
|
4256
|
+
*
|
|
4257
|
+
* // Replace "needs correction" with "is correct"
|
|
4258
|
+
* const result = range.replaceText(
|
|
4259
|
+
* { index: 10, length: 16 },
|
|
4260
|
+
* "is correct"
|
|
4261
|
+
* );
|
|
4262
|
+
*
|
|
4263
|
+
* // The bounds of the replaced text are returned
|
|
4264
|
+
* // Do something with the bounds - result.bounds, e.g. { index: 10, length: 10 }
|
|
4265
|
+
* ```
|
|
4266
|
+
*
|
|
4267
|
+
* @example Replace text with formatted text
|
|
4268
|
+
* ```typescript
|
|
4269
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4270
|
+
*
|
|
4271
|
+
* const range = createRichtextRange();
|
|
4272
|
+
* range.appendText("Regular text that needs emphasis.");
|
|
4273
|
+
*
|
|
4274
|
+
* // Replace "needs emphasis" with formatted text
|
|
4275
|
+
* range.replaceText(
|
|
4276
|
+
* { index: 17, length: 15 },
|
|
4277
|
+
* "is important",
|
|
4278
|
+
* {
|
|
4279
|
+
* fontWeight: 'bold',
|
|
4280
|
+
* fontStyle: 'italic',
|
|
4281
|
+
* color: '#0066CC'
|
|
4282
|
+
* }
|
|
4283
|
+
* );
|
|
4284
|
+
* ```
|
|
4285
|
+
*/
|
|
4286
|
+
replaceText(bounds: Bounds, characters: string, formatting?: InlineFormatting): {
|
|
4287
|
+
/**
|
|
4288
|
+
* The bounds of the replacement characters within the updated range.
|
|
4289
|
+
*/
|
|
4290
|
+
bounds: Bounds;
|
|
4291
|
+
};
|
|
4292
|
+
/**
|
|
4293
|
+
* Returns the current state of the richtext as plaintext.
|
|
4294
|
+
*
|
|
4295
|
+
* @example Extract plain text content
|
|
4296
|
+
* ```typescript
|
|
4297
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4298
|
+
*
|
|
4299
|
+
* const range = createRichtextRange();
|
|
4300
|
+
* range.appendText("First paragraph.\n", { fontWeight: 'bold' });
|
|
4301
|
+
* range.appendText("Second paragraph with formatting.", { color: '#FF0000' });
|
|
4302
|
+
*
|
|
4303
|
+
* // Get plain text content without formatting
|
|
4304
|
+
* const plainText = range.readPlaintext();
|
|
4305
|
+
* // Do something with the plain text - plainText, e.g. "First paragraph.\nSecond paragraph with formatting."
|
|
4306
|
+
* ```
|
|
4307
|
+
*
|
|
4308
|
+
* @example Search within text content
|
|
4309
|
+
* ```typescript
|
|
4310
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4311
|
+
*
|
|
4312
|
+
* const range = createRichtextRange();
|
|
4313
|
+
* range.appendText("This text contains a searchable term.");
|
|
4314
|
+
*
|
|
4315
|
+
* // Search for a specific word
|
|
4316
|
+
* const plainText = range.readPlaintext();
|
|
4317
|
+
* const searchTerm = "searchable";
|
|
4318
|
+
* const index = plainText.indexOf(searchTerm);
|
|
4319
|
+
*
|
|
4320
|
+
* if (index !== -1) {
|
|
4321
|
+
* // Format the found term
|
|
4322
|
+
* range.formatText(
|
|
4323
|
+
* { index, length: searchTerm.length },
|
|
4324
|
+
* { fontWeight: 'bold', decoration: 'underline' }
|
|
4325
|
+
* );
|
|
4326
|
+
* }
|
|
4327
|
+
* ```
|
|
4328
|
+
*/
|
|
4329
|
+
readPlaintext(): string;
|
|
4330
|
+
/**
|
|
4331
|
+
* Returns the current state of the richtext as one or more text regions.
|
|
4332
|
+
* Each region is an object that contains the text content and its formatting.
|
|
4333
|
+
*
|
|
4334
|
+
* @example Get text with formatting information
|
|
4335
|
+
* ```typescript
|
|
4336
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4337
|
+
*
|
|
4338
|
+
* const range = createRichtextRange();
|
|
4339
|
+
* range.appendText("Normal text ", {});
|
|
4340
|
+
* range.appendText("bold text", { fontWeight: 'bold' });
|
|
4341
|
+
* range.appendText(" and ", {});
|
|
4342
|
+
* range.appendText("red text", { color: '#FF0000' });
|
|
4343
|
+
*
|
|
4344
|
+
* // Get formatted regions
|
|
4345
|
+
* const regions = range.readTextRegions();
|
|
4346
|
+
* // Do something with the regions, e.g.
|
|
4347
|
+
* // [
|
|
4348
|
+
* // { text: "Normal text ", formatting: {} },
|
|
4349
|
+
* // { text: "bold text", formatting: { fontWeight: 'bold' } },
|
|
4350
|
+
* // { text: " and ", formatting: {} },
|
|
4351
|
+
* // { text: "red text", formatting: { color: '#FF0000' } }
|
|
4352
|
+
* // ]
|
|
4353
|
+
* ```
|
|
4354
|
+
*
|
|
4355
|
+
* @example Analyze formatting variations
|
|
4356
|
+
* ```typescript
|
|
4357
|
+
* import { createRichtextRange } from "@canva/design";
|
|
4358
|
+
*
|
|
4359
|
+
* const range = createRichtextRange();
|
|
4360
|
+
* range.appendText("Mixed ", {});
|
|
4361
|
+
* range.appendText("formatted ", { fontWeight: 'bold' });
|
|
4362
|
+
* range.appendText("text", { color: '#0066CC' });
|
|
4363
|
+
*
|
|
4364
|
+
* // Analyze formatting variations
|
|
4365
|
+
* const regions = range.readTextRegions();
|
|
4366
|
+
* const formattingTypes = regions.map(region => {
|
|
4367
|
+
* const formatting = region.formatting || {};
|
|
4368
|
+
* return {
|
|
4369
|
+
* text: region.text,
|
|
4370
|
+
* hasWeight: !!formatting.fontWeight,
|
|
4371
|
+
* hasColor: !!formatting.color
|
|
4372
|
+
* };
|
|
4373
|
+
* });
|
|
4374
|
+
* ```
|
|
4375
|
+
*/
|
|
4376
|
+
readTextRegions(): TextRegion[];
|
|
4377
|
+
};
|
|
4378
|
+
|
|
4379
|
+
/**
|
|
4380
|
+
* @public
|
|
4381
|
+
* An alias for the DesignSelection interface, providing access to design selection related functionality
|
|
4382
|
+
*/
|
|
4383
|
+
export declare const selection: DesignSelection;
|
|
4384
|
+
|
|
4385
|
+
/**
|
|
4386
|
+
* @public
|
|
4387
|
+
* Information about the user's selection. To access the selected content, call the `read` method.
|
|
4388
|
+
*/
|
|
4389
|
+
export declare interface SelectionEvent<Scope extends SelectionScope> {
|
|
4390
|
+
/**
|
|
4391
|
+
* The type of content that's selected.
|
|
4392
|
+
*/
|
|
4393
|
+
readonly scope: Scope;
|
|
4394
|
+
/**
|
|
4395
|
+
* The number of selected elements.
|
|
4396
|
+
*/
|
|
4397
|
+
readonly count: number;
|
|
4398
|
+
/**
|
|
4399
|
+
* Creates a snapshot of the selected content and returns a *draft* object.
|
|
4400
|
+
* The draft has a mutable `contents` property for making changes to the selected content.
|
|
4401
|
+
* Any changes made to `contents` are not immediately persisted or reflected in the user's design.
|
|
4402
|
+
* To persist the changes, call the `save` method that's available via the draft.
|
|
4403
|
+
*
|
|
4404
|
+
* @example Read and modify plaintext selection
|
|
4405
|
+
* ```typescript
|
|
4406
|
+
* import { selection } from "@canva/design";
|
|
4407
|
+
*
|
|
4408
|
+
* selection.registerOnChange({
|
|
4409
|
+
* scope: 'plaintext',
|
|
4410
|
+
* onChange: async (event) => {
|
|
4411
|
+
* if (event.count > 0) {
|
|
4412
|
+
* // Read the content
|
|
4413
|
+
* const draft = await event.read();
|
|
4414
|
+
*
|
|
4415
|
+
* // Handle selected text `draft.contents[0].text`
|
|
4416
|
+
*
|
|
4417
|
+
* // Modify the text if needed
|
|
4418
|
+
* // draft.contents[0].text = 'Modified text';
|
|
4419
|
+
* // await draft.save();
|
|
4420
|
+
* }
|
|
4421
|
+
* }
|
|
4422
|
+
* });
|
|
4423
|
+
* ```
|
|
4424
|
+
*
|
|
4425
|
+
* @example Read and analyze image selection
|
|
4426
|
+
* ```typescript
|
|
4427
|
+
* import { selection } from "@canva/design";
|
|
4428
|
+
*
|
|
4429
|
+
* selection.registerOnChange({
|
|
4430
|
+
* scope: 'image',
|
|
4431
|
+
* onChange: async (event) => {
|
|
4432
|
+
* // Check if any images are selected
|
|
4433
|
+
* if (event.count === 0) {
|
|
4434
|
+
* // Handle no images selected case
|
|
4435
|
+
* return;
|
|
4436
|
+
* }
|
|
4437
|
+
*
|
|
4438
|
+
* // Read the content
|
|
4439
|
+
* const draft = await event.read();
|
|
4440
|
+
*
|
|
4441
|
+
* // Get information about selected images
|
|
4442
|
+
* const imageRefs = draft.contents.map(content => content.ref);
|
|
4443
|
+
*
|
|
4444
|
+
* // The ref can be used with other API methods
|
|
4445
|
+
* }
|
|
4446
|
+
* });
|
|
4447
|
+
* ```
|
|
4448
|
+
*
|
|
4449
|
+
* @example Process multiple selected items
|
|
4450
|
+
* ```typescript
|
|
4451
|
+
* import { selection } from "@canva/design";
|
|
4452
|
+
*
|
|
4453
|
+
* selection.registerOnChange({
|
|
4454
|
+
* scope: 'richtext',
|
|
4455
|
+
* onChange: async (event) => {
|
|
4456
|
+
* if (event.count > 0) {
|
|
4457
|
+
* const draft = await event.read();
|
|
4458
|
+
*
|
|
4459
|
+
* // Process each selected range
|
|
4460
|
+
* draft.contents.forEach((range) => {
|
|
4461
|
+
* // Do something with the range content and formatted regions, with `range.readPlaintext()` and `range.readTextRegions()`
|
|
4462
|
+
* });
|
|
4463
|
+
* }
|
|
4464
|
+
* }
|
|
4465
|
+
* });
|
|
4466
|
+
* ```
|
|
4467
|
+
*/
|
|
4468
|
+
read(): Promise<ContentDraft<SelectionValue<Scope>>>;
|
|
4469
|
+
}
|
|
4470
|
+
|
|
4471
|
+
/**
|
|
4472
|
+
* @public
|
|
4473
|
+
* Information about a user's selection.
|
|
4474
|
+
*/
|
|
4475
|
+
export declare interface SelectionEvent<Scope extends SelectionScope> {
|
|
4476
|
+
/**
|
|
4477
|
+
* The type of content.
|
|
4478
|
+
*/
|
|
4479
|
+
readonly scope: Scope;
|
|
4480
|
+
/**
|
|
4481
|
+
* The number of content items in the user's selection.
|
|
4482
|
+
*/
|
|
4483
|
+
readonly count: number;
|
|
4484
|
+
/**
|
|
4485
|
+
* Returns a snapshot of the content in the user's selection.
|
|
4486
|
+
*
|
|
4487
|
+
* @remarks
|
|
4488
|
+
* The snapshot is known as the *draft*.
|
|
4489
|
+
*/
|
|
4490
|
+
read(): Promise<ContentDraft<SelectionValue<Scope>>>;
|
|
4491
|
+
}
|
|
4492
|
+
|
|
4493
|
+
/**
|
|
4494
|
+
* @public
|
|
4495
|
+
* A type of content that supports selection events.
|
|
4496
|
+
*/
|
|
4497
|
+
export declare type SelectionScope = 'plaintext' | 'image' | 'video' | 'richtext';
|
|
4498
|
+
|
|
4499
|
+
/**
|
|
4500
|
+
* @public
|
|
4501
|
+
* A piece of selected content.
|
|
4502
|
+
*
|
|
4503
|
+
* @remarks
|
|
4504
|
+
* The available properties depend on the type (scope) of content.
|
|
4505
|
+
*/
|
|
4506
|
+
export declare type SelectionValue<Scope extends SelectionScope> = {
|
|
4507
|
+
/**
|
|
4508
|
+
* A selected range of plaintext.
|
|
4509
|
+
*/
|
|
4510
|
+
['plaintext']: {
|
|
4511
|
+
/**
|
|
4512
|
+
* The text content.
|
|
4513
|
+
*/
|
|
4514
|
+
text: string;
|
|
4515
|
+
};
|
|
4516
|
+
/**
|
|
4517
|
+
* A selected image.
|
|
4518
|
+
*/
|
|
4519
|
+
['image']: {
|
|
4520
|
+
/**
|
|
4521
|
+
* A unique identifier that points to an image asset in Canva's backend.
|
|
4522
|
+
*/
|
|
4523
|
+
ref: ImageRef;
|
|
4524
|
+
};
|
|
4525
|
+
/**
|
|
4526
|
+
* A selected video.
|
|
4527
|
+
*/
|
|
4528
|
+
['video']: {
|
|
4529
|
+
/**
|
|
4530
|
+
* A unique identifier that points to an video asset in Canva's backend.
|
|
4531
|
+
*/
|
|
4532
|
+
ref: VideoRef;
|
|
4533
|
+
};
|
|
4534
|
+
/**
|
|
4535
|
+
* A selected range of formatted text.
|
|
4536
|
+
*/
|
|
4537
|
+
['richtext']: RichtextRange;
|
|
4538
|
+
}[Scope];
|
|
4539
|
+
|
|
4540
|
+
/**
|
|
4541
|
+
* @public
|
|
4542
|
+
* Updates the background of the user's current page. The background can be a solid color,
|
|
4543
|
+
* an image or a video.
|
|
4544
|
+
*
|
|
4545
|
+
* @example Set background color
|
|
4546
|
+
* ```typescript
|
|
4547
|
+
* import { setCurrentPageBackground } from "@canva/design";
|
|
4548
|
+
* import type { PageBackgroundFill } from "@canva/design";
|
|
4549
|
+
*
|
|
4550
|
+
* const background: PageBackgroundFill = {
|
|
4551
|
+
* color: '#F5F5F5',
|
|
4552
|
+
* };
|
|
4553
|
+
*
|
|
4554
|
+
* await setCurrentPageBackground(background);
|
|
4555
|
+
* ```
|
|
4556
|
+
*
|
|
4557
|
+
* @example Set background image
|
|
4558
|
+
* ```typescript
|
|
4559
|
+
* import { setCurrentPageBackground } from "@canva/design";
|
|
4560
|
+
* import type { PageBackgroundFill } from "@canva/design";
|
|
4561
|
+
* import type { ImageRef } from "@canva/asset";
|
|
4562
|
+
*
|
|
4563
|
+
* const exampleImageRef = "YOUR_IMAGE_REF" as ImageRef;
|
|
4564
|
+
*
|
|
4565
|
+
* const background: PageBackgroundFill = {
|
|
4566
|
+
* asset: {
|
|
4567
|
+
* type: 'image',
|
|
4568
|
+
* ref: exampleImageRef,
|
|
4569
|
+
* altText: { text: 'Background image', decorative: true }
|
|
4570
|
+
* },
|
|
4571
|
+
* };
|
|
4572
|
+
*
|
|
4573
|
+
* await setCurrentPageBackground(background);
|
|
4574
|
+
* ```
|
|
4575
|
+
*
|
|
4576
|
+
* @example Set background video
|
|
4577
|
+
* ```typescript
|
|
4578
|
+
* import { setCurrentPageBackground } from "@canva/design";
|
|
4579
|
+
* import type { PageBackgroundFill } from "@canva/design";
|
|
4580
|
+
* import type { VideoRef } from "@canva/asset";
|
|
4581
|
+
*
|
|
4582
|
+
* const exampleVideoRef = "YOUR_VIDEO_REF" as VideoRef;
|
|
4583
|
+
*
|
|
4584
|
+
* const background: PageBackgroundFill = {
|
|
4585
|
+
* asset: {
|
|
4586
|
+
* type: 'video',
|
|
4587
|
+
* ref: exampleVideoRef,
|
|
4588
|
+
* altText: { text: 'Background video', decorative: true }
|
|
4589
|
+
* },
|
|
4590
|
+
* };
|
|
4591
|
+
*
|
|
4592
|
+
* await setCurrentPageBackground(background);
|
|
4593
|
+
* ```
|
|
4594
|
+
*/
|
|
4595
|
+
export declare const setCurrentPageBackground: (opts: PageBackgroundFill) => Promise<void>;
|
|
4596
|
+
|
|
4597
|
+
/**
|
|
4598
|
+
* @public
|
|
4599
|
+
* An element that renders a vector shape.
|
|
4600
|
+
*/
|
|
4601
|
+
export declare type ShapeElement = {
|
|
4602
|
+
/**
|
|
4603
|
+
* The type of element.
|
|
4604
|
+
*/
|
|
4605
|
+
type: 'shape';
|
|
4606
|
+
/**
|
|
4607
|
+
* Options for configuring the scale and cropping of the shape.
|
|
4608
|
+
*/
|
|
4609
|
+
viewBox: ShapeViewBox;
|
|
4610
|
+
/**
|
|
4611
|
+
* The paths that define the structure of the shape.
|
|
4612
|
+
*
|
|
4613
|
+
* @remarks
|
|
4614
|
+
* - There must be between 1 and 30 paths (inclusive).
|
|
4615
|
+
* - The maximum combined size of all paths must not exceed 2kb.
|
|
4616
|
+
* - The maximum number of unique fill colors across all paths is 6.
|
|
4617
|
+
*/
|
|
4618
|
+
paths: ShapePath[];
|
|
4619
|
+
};
|
|
4620
|
+
|
|
4621
|
+
/**
|
|
4622
|
+
* @public
|
|
4623
|
+
* An element that renders a vector shape and has positional properties.
|
|
4624
|
+
*/
|
|
4625
|
+
export declare type ShapeElementAtPoint = ShapeElement & Point & (WidthAndHeight | Width | Height);
|
|
4626
|
+
|
|
4627
|
+
/**
|
|
4628
|
+
* @public
|
|
4629
|
+
* A path that defines the structure of a shape element.
|
|
4630
|
+
*/
|
|
4631
|
+
export declare type ShapePath = {
|
|
4632
|
+
/**
|
|
4633
|
+
* The shape of the path.
|
|
4634
|
+
*
|
|
4635
|
+
* @remarks
|
|
4636
|
+
* This is similar to the `d` attribute of an SVG's `path` element, with some limitations:
|
|
4637
|
+
*
|
|
4638
|
+
* - The path must start with an M command.
|
|
4639
|
+
* - The path must not have more than one M command.
|
|
4640
|
+
* - The path must not use the Q command.
|
|
4641
|
+
* - The path must be closed, either by:
|
|
4642
|
+
* - Using a Z command at the end of the path
|
|
4643
|
+
* - Having the last coordinate match the first coordinate
|
|
4644
|
+
*/
|
|
4645
|
+
d: string;
|
|
4646
|
+
/**
|
|
4647
|
+
* The appearance of the path's interior.
|
|
4648
|
+
*/
|
|
4649
|
+
fill: Fill;
|
|
4650
|
+
/**
|
|
4651
|
+
* The outline of the path.
|
|
4652
|
+
*/
|
|
4653
|
+
stroke?: PathStroke;
|
|
4654
|
+
};
|
|
4655
|
+
|
|
4656
|
+
/**
|
|
4657
|
+
* @public
|
|
4658
|
+
* Options for configuring the scale and cropping of a shape.
|
|
4659
|
+
*
|
|
4660
|
+
* @remarks
|
|
4661
|
+
* This is similar to the `viewBox` attribute of an `SVGElement`.
|
|
4662
|
+
*/
|
|
4663
|
+
export declare type ShapeViewBox = {
|
|
4664
|
+
/**
|
|
4665
|
+
* The distance of the shape from the top edge of the element, in pixels.
|
|
4666
|
+
*/
|
|
4667
|
+
top: number;
|
|
4668
|
+
/**
|
|
4669
|
+
* The distance of the shape from the left edge of the element, in pixels.
|
|
4670
|
+
*/
|
|
4671
|
+
left: number;
|
|
4672
|
+
/**
|
|
4673
|
+
* The width of the view box, in pixels.
|
|
4674
|
+
*/
|
|
4675
|
+
width: number;
|
|
4676
|
+
/**
|
|
4677
|
+
* The height of the view box, in pixels.
|
|
4678
|
+
*/
|
|
4679
|
+
height: number;
|
|
4680
|
+
};
|
|
4681
|
+
|
|
4682
|
+
/**
|
|
4683
|
+
* @public
|
|
4684
|
+
* An element that renders a table.
|
|
4685
|
+
*/
|
|
4686
|
+
export declare type TableElement = {
|
|
4687
|
+
/**
|
|
4688
|
+
* The type of element.
|
|
4689
|
+
*/
|
|
4690
|
+
type: 'table';
|
|
4691
|
+
/**
|
|
4692
|
+
* The rows of the table.
|
|
4693
|
+
*/
|
|
4694
|
+
rows: {
|
|
4695
|
+
/**
|
|
4696
|
+
* The cells (columns) of the row.
|
|
4697
|
+
*
|
|
4698
|
+
* @remarks
|
|
4699
|
+
* Each row must have the same number of cells.
|
|
4700
|
+
*/
|
|
4701
|
+
cells: (Cell | null | undefined)[];
|
|
4702
|
+
}[];
|
|
4703
|
+
};
|
|
4704
|
+
|
|
4705
|
+
/**
|
|
4706
|
+
* @public
|
|
4707
|
+
* Options for configuring the appearance of text.
|
|
4708
|
+
*/
|
|
4709
|
+
export declare type TextAttributes = {
|
|
4710
|
+
/**
|
|
4711
|
+
* The size of the text.
|
|
4712
|
+
*
|
|
4713
|
+
* @remarks
|
|
4714
|
+
* - Minimum: 1
|
|
4715
|
+
* - Maximum: 100
|
|
4716
|
+
*
|
|
4717
|
+
* @defaultValue 16
|
|
4718
|
+
*/
|
|
4719
|
+
fontSize?: number;
|
|
4720
|
+
/**
|
|
4721
|
+
* The alignment of the text.
|
|
4722
|
+
* @defaultValue "start"
|
|
4723
|
+
*/
|
|
4724
|
+
textAlign?: 'start' | 'center' | 'end' | 'justify';
|
|
4725
|
+
/**
|
|
4726
|
+
* The color of the text as a hex code.
|
|
4727
|
+
*
|
|
4728
|
+
* @remarks
|
|
4729
|
+
* The hex code must include all six characters and be prefixed with a `#` symbol.
|
|
4730
|
+
*
|
|
4731
|
+
* @example
|
|
4732
|
+
* "#ff0099"
|
|
4733
|
+
*/
|
|
4734
|
+
color?: string;
|
|
4735
|
+
/**
|
|
4736
|
+
* @public
|
|
4737
|
+
* A unique identifier that points to a font asset in Canva's backend.
|
|
4738
|
+
*/
|
|
4739
|
+
fontRef?: FontRef;
|
|
4740
|
+
/**
|
|
4741
|
+
* The weight (thickness) of the font.
|
|
4742
|
+
* @defaultValue "normal"
|
|
4743
|
+
*/
|
|
4744
|
+
fontWeight?: FontWeight;
|
|
4745
|
+
/**
|
|
4746
|
+
* The style of the font.
|
|
4747
|
+
* @defaultValue "normal"
|
|
4748
|
+
*/
|
|
4749
|
+
fontStyle?: 'normal' | 'italic';
|
|
4750
|
+
/**
|
|
4751
|
+
* The decoration of the font.
|
|
4752
|
+
* @defaultValue "none"
|
|
4753
|
+
*/
|
|
4754
|
+
decoration?: 'none' | 'underline';
|
|
4755
|
+
};
|
|
4756
|
+
|
|
4757
|
+
/**
|
|
4758
|
+
* @public
|
|
4759
|
+
* The dimensions, position, and rotation of a text element.
|
|
4760
|
+
*/
|
|
4761
|
+
declare type TextBox = Point & {
|
|
4762
|
+
/**
|
|
4763
|
+
* The width of the element, in pixels.
|
|
4764
|
+
*
|
|
4765
|
+
* @remarks
|
|
4766
|
+
* - Minimum: 0
|
|
4767
|
+
* - Maximum: 32767
|
|
4768
|
+
*/
|
|
4769
|
+
width?: number;
|
|
4770
|
+
};
|
|
4771
|
+
|
|
4772
|
+
/**
|
|
4773
|
+
* @public
|
|
4774
|
+
* Text element or content to be added to the design at the end of a drag event.
|
|
4775
|
+
*/
|
|
4776
|
+
export declare type TextDragConfig = {
|
|
4777
|
+
/**
|
|
4778
|
+
* The type of element.
|
|
4779
|
+
*/
|
|
4780
|
+
type: 'text';
|
|
4781
|
+
/**
|
|
4782
|
+
* The text content to drag.
|
|
4783
|
+
*/
|
|
4784
|
+
children?: string[];
|
|
4785
|
+
/**
|
|
4786
|
+
* The alignment of the text.
|
|
4787
|
+
* @defaultValue "start"
|
|
4788
|
+
*/
|
|
4789
|
+
textAlign?: 'start' | 'center' | 'end' | 'justify';
|
|
4790
|
+
/**
|
|
4791
|
+
* The weight (thickness) of the font.
|
|
4792
|
+
* @defaultValue "normal"
|
|
4793
|
+
*/
|
|
4794
|
+
fontWeight?: FontWeight;
|
|
4795
|
+
/**
|
|
4796
|
+
* The style of the font.
|
|
4797
|
+
* @defaultValue "normal"
|
|
4798
|
+
*/
|
|
4799
|
+
fontStyle?: 'normal' | 'italic';
|
|
4800
|
+
/**
|
|
4801
|
+
* The decoration of the font.
|
|
4802
|
+
* @defaultValue "none"
|
|
4803
|
+
*/
|
|
4804
|
+
decoration?: 'none' | 'underline';
|
|
4805
|
+
|
|
4806
|
+
};
|
|
4807
|
+
|
|
4808
|
+
/**
|
|
4809
|
+
* @public
|
|
4810
|
+
* An element that renders text content.
|
|
4811
|
+
*/
|
|
4812
|
+
export declare type TextElement = {
|
|
4813
|
+
/**
|
|
4814
|
+
* The type of element.
|
|
4815
|
+
*/
|
|
4816
|
+
type: 'text';
|
|
4817
|
+
/**
|
|
4818
|
+
* The text content.
|
|
4819
|
+
*
|
|
4820
|
+
* @remarks
|
|
4821
|
+
* Only the first element in this array is used.
|
|
4822
|
+
*/
|
|
4823
|
+
children: string[];
|
|
4824
|
+
} & TextAttributes;
|
|
4825
|
+
|
|
4826
|
+
/**
|
|
4827
|
+
* @public
|
|
4828
|
+
* An element that renders text content and has positional properties.
|
|
4829
|
+
*/
|
|
4830
|
+
export declare type TextElementAtPoint = TextElement & TextBox;
|
|
4831
|
+
|
|
4832
|
+
/**
|
|
4833
|
+
* @public
|
|
4834
|
+
* A region of richtext.
|
|
4835
|
+
*/
|
|
4836
|
+
export declare type TextRegion = {
|
|
4837
|
+
/**
|
|
4838
|
+
* The plaintext content of the region.
|
|
4839
|
+
*/
|
|
4840
|
+
text: string;
|
|
4841
|
+
/**
|
|
4842
|
+
* The formatting of the region.
|
|
4843
|
+
*/
|
|
4844
|
+
formatting?: Partial<RichtextFormatting>;
|
|
4845
|
+
};
|
|
4846
|
+
|
|
4847
|
+
/**
|
|
4848
|
+
* @public
|
|
4849
|
+
* Provides methods for adding drag and drop behavior to an app.
|
|
4850
|
+
*/
|
|
4851
|
+
export declare interface UI {
|
|
4852
|
+
/**
|
|
4853
|
+
* @deprecated The method has been superseded by `startDragToPoint`.
|
|
4854
|
+
* @public
|
|
4855
|
+
* Adds the specified element or content to a design at the end of a drag event.
|
|
4856
|
+
*
|
|
4857
|
+
* @param event - A drag start event.
|
|
4858
|
+
* @param dragData - Element or content to be added to the design at the end of the drag event.
|
|
4859
|
+
*/
|
|
4860
|
+
startDrag<E extends Element>(event: DragStartEvent<E>, dragData: TextDragConfig | AudioDragConfig | EmbedDragConfig | VideoDragConfigForElement<E> | ImageDragConfigForElement<E>): Promise<void>;
|
|
4861
|
+
/**
|
|
4862
|
+
* @public
|
|
4863
|
+
* Adds the specified element or content to fixed designs, which use a coordinate-based positioning system at the end of a drag event.
|
|
4864
|
+
*
|
|
4865
|
+
* @param event - A drag start event.
|
|
4866
|
+
* @param dragData - Element or content to be added to the design at the end of the drag event.
|
|
4867
|
+
*/
|
|
4868
|
+
startDragToPoint<E extends Element>(event: DragStartEvent<E>, dragData: TextDragConfig | AudioDragConfig | EmbedDragConfig | VideoDragConfigForElement<E> | ImageDragConfigForElement<E>): Promise<void>;
|
|
4869
|
+
/**
|
|
4870
|
+
* @public
|
|
4871
|
+
* Adds the specified element or content to responsive documents, which slot things into a text stream at the end of a drag event.
|
|
4872
|
+
*
|
|
4873
|
+
* @param event - A drag start event.
|
|
4874
|
+
* @param dragData - Element or content to be added to the design at the end of the drag event.
|
|
4875
|
+
*/
|
|
4876
|
+
startDragToCursor<E extends Element>(event: DragStartEvent<E>, dragData: EmbedDragConfig | VideoDragConfigForElement<E> | ImageDragConfigForElement<E>): Promise<void>;
|
|
4877
|
+
}
|
|
4878
|
+
|
|
4879
|
+
/**
|
|
4880
|
+
* An alias for the UI interface, providing access to ui related functionality
|
|
4881
|
+
* @public
|
|
4882
|
+
*/
|
|
4883
|
+
export declare const ui: UI;
|
|
4884
|
+
|
|
4885
|
+
/**
|
|
4886
|
+
* @public
|
|
4887
|
+
* A data type that can be used in app element data.
|
|
4888
|
+
*/
|
|
4889
|
+
export declare type Value = Primitive | ObjectPrimitive | Exclude<Value, undefined>[] | {
|
|
4890
|
+
[key: string]: Value;
|
|
4891
|
+
};
|
|
4892
|
+
|
|
4893
|
+
/**
|
|
4894
|
+
* @public
|
|
4895
|
+
* Video element or content to be added to the design at the end of a drag event.
|
|
4896
|
+
*/
|
|
4897
|
+
export declare type VideoDragConfig = {
|
|
4898
|
+
/**
|
|
4899
|
+
* The type of element.
|
|
4900
|
+
*/
|
|
4901
|
+
type: 'video';
|
|
4902
|
+
/**
|
|
4903
|
+
* A function that returns a reference (ref) to a video asset in Canva's backend.
|
|
4904
|
+
*/
|
|
4905
|
+
resolveVideoRef: () => Promise<{
|
|
4906
|
+
ref: VideoRef;
|
|
4907
|
+
}>;
|
|
4908
|
+
/**
|
|
4909
|
+
* The dimensions of the preview image.
|
|
4910
|
+
*/
|
|
4911
|
+
previewSize: Dimensions;
|
|
4912
|
+
/**
|
|
4913
|
+
* The dimensions of the full-size video.
|
|
4914
|
+
*
|
|
4915
|
+
* @remarks
|
|
4916
|
+
* - These dimensions are used when adding the video to the design
|
|
4917
|
+
* - If omitted, the `previewSize` dimensions are used as a fallback.
|
|
4918
|
+
*/
|
|
4919
|
+
fullSize?: Dimensions;
|
|
4920
|
+
/**
|
|
4921
|
+
* The URL of an image to display under the user's cursor during the drag and drop event.
|
|
4922
|
+
*/
|
|
4923
|
+
previewUrl: string;
|
|
4924
|
+
};
|
|
4925
|
+
|
|
4926
|
+
/**
|
|
4927
|
+
* @public
|
|
4928
|
+
* Video element or content to be added to the design at the end of a drag event.
|
|
4929
|
+
*/
|
|
4930
|
+
export declare type VideoDragConfigForElement<E extends Element> = E extends HTMLImageElement ? Partial<VideoDragConfig> & Pick<VideoDragConfig, 'type' | 'resolveVideoRef'> : VideoDragConfig;
|
|
4931
|
+
|
|
4932
|
+
/**
|
|
4933
|
+
* @public
|
|
4934
|
+
* An element that renders video content.
|
|
4935
|
+
*/
|
|
4936
|
+
export declare type VideoElement = {
|
|
4937
|
+
/**
|
|
4938
|
+
* The type of element.
|
|
4939
|
+
*/
|
|
4940
|
+
type: 'video';
|
|
4941
|
+
/**
|
|
4942
|
+
* A unique identifier that points to a video asset in Canva's backend.
|
|
4943
|
+
*/
|
|
4944
|
+
ref: VideoRef;
|
|
4945
|
+
/**
|
|
4946
|
+
* A description of the video content.
|
|
4947
|
+
*
|
|
4948
|
+
* @remarks
|
|
4949
|
+
* Use `undefined` for content with no description.
|
|
4950
|
+
*/
|
|
4951
|
+
altText: AltText | undefined;
|
|
4952
|
+
};
|
|
4953
|
+
|
|
4954
|
+
/**
|
|
4955
|
+
* @public
|
|
4956
|
+
* An element that renders video content and has positional properties.
|
|
4957
|
+
*/
|
|
4958
|
+
export declare type VideoElementAtPoint = VideoElement & Point & (WidthAndHeight | Width | Height);
|
|
4959
|
+
|
|
4960
|
+
/**
|
|
4961
|
+
* @public
|
|
4962
|
+
* A video asset that fills a path's interior.
|
|
4963
|
+
*/
|
|
4964
|
+
export declare type VideoFill = {
|
|
4965
|
+
/**
|
|
4966
|
+
* The type of fill.
|
|
4967
|
+
*/
|
|
4968
|
+
type: 'video';
|
|
4969
|
+
/**
|
|
4970
|
+
* A unique identifier that points to a video asset in Canva's backend.
|
|
4971
|
+
*/
|
|
4972
|
+
ref: VideoRef;
|
|
4973
|
+
/**
|
|
4974
|
+
* A description of the image content.
|
|
4975
|
+
*
|
|
4976
|
+
* @remarks
|
|
4977
|
+
* Use `undefined` for content with no description.
|
|
4978
|
+
*/
|
|
4979
|
+
altText?: AltText;
|
|
4980
|
+
};
|
|
4981
|
+
|
|
4982
|
+
/**
|
|
4983
|
+
* @public
|
|
4984
|
+
* A unique identifier that references a video asset in Canva's backend.
|
|
4985
|
+
*/
|
|
4986
|
+
export declare type VideoRef = string & {
|
|
4987
|
+
__videoRef: never;
|
|
4988
|
+
};
|
|
4989
|
+
|
|
4990
|
+
/**
|
|
4991
|
+
* A set of dimensions with an auto-calculated height.
|
|
4992
|
+
*/
|
|
4993
|
+
declare type Width = {
|
|
4994
|
+
/**
|
|
4995
|
+
* A width, in pixels.
|
|
4996
|
+
*
|
|
4997
|
+
* @remarks
|
|
4998
|
+
* - The pixels are relative to their container.
|
|
4999
|
+
* - Minimum: 0
|
|
5000
|
+
* - Maximum: 32767
|
|
5001
|
+
*/
|
|
5002
|
+
width: number;
|
|
5003
|
+
/**
|
|
5004
|
+
* Indicates that the height should be auto-calculated.
|
|
5005
|
+
*/
|
|
5006
|
+
height: 'auto';
|
|
5007
|
+
};
|
|
5008
|
+
|
|
5009
|
+
/**
|
|
5010
|
+
* A set of dimensions, in pixels.
|
|
5011
|
+
*/
|
|
5012
|
+
declare type WidthAndHeight = {
|
|
5013
|
+
/**
|
|
5014
|
+
* A width, in pixels.
|
|
5015
|
+
*
|
|
5016
|
+
* @remarks
|
|
5017
|
+
* - The pixels are relative to their container.
|
|
5018
|
+
* - Minimum: 0
|
|
5019
|
+
* - Maximum: 32767
|
|
5020
|
+
*/
|
|
5021
|
+
width: number;
|
|
5022
|
+
/**
|
|
5023
|
+
* A height, in pixels.
|
|
5024
|
+
*
|
|
5025
|
+
* @remarks
|
|
5026
|
+
* - The pixels are relative to their container.
|
|
5027
|
+
* - Minimum: 0
|
|
5028
|
+
* - Maximum: 32767
|
|
5029
|
+
*/
|
|
5030
|
+
height: number;
|
|
5031
|
+
};
|
|
5032
|
+
|
|
5033
|
+
/**
|
|
5034
|
+
* @public
|
|
5035
|
+
* The behavior of zipping the exported files.
|
|
5036
|
+
*
|
|
5037
|
+
* @remarks
|
|
5038
|
+
* For `png`, `jpg`, and `svg`:
|
|
5039
|
+
* - `auto` (default): Files are zipped together if the design has multiple pages, unzipped if it has one page.
|
|
5040
|
+
* - `always`: Files are always zipped into a single zip file, regardless of page count.
|
|
5041
|
+
* - `never`: Files are never zipped, providing an array of files.
|
|
5042
|
+
*
|
|
5043
|
+
* For `video` and `gif`:
|
|
5044
|
+
* - `auto` or `never` (default): Files are never zipped together, regardless of count.
|
|
5045
|
+
* - `always`: Files are always zipped into a single file.
|
|
5046
|
+
*/
|
|
5047
|
+
export declare type ZipBehavior = 'auto' | 'always' | 'never';
|
|
5048
|
+
|
|
5049
|
+
export { }
|