fika-editor 3.2.9 → 3.3.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.
Files changed (103) hide show
  1. package/dist/embed/{824.js → 6104.js} +18 -18
  2. package/dist/embed/agentic-manifest.json +46 -10
  3. package/dist/embed/chunks/1131.js +1 -1
  4. package/dist/embed/chunks/2407.js +1 -1
  5. package/dist/embed/chunks/2807.js +1 -1
  6. package/dist/embed/chunks/3888.js +1 -1
  7. package/dist/embed/chunks/5216.js +1 -1
  8. package/dist/embed/chunks/574.js +1 -1
  9. package/dist/embed/chunks/655.js +1 -0
  10. package/dist/embed/chunks/862.js +1 -1
  11. package/dist/embed/chunks/9657.js +1 -1
  12. package/dist/embed/chunks/9800.js +1 -1
  13. package/dist/embed/fika-embed.css +1 -1
  14. package/dist/embed/fika-embed.js +18 -4
  15. package/dist/layout/types/slides.js +1 -0
  16. package/dist/layout/utils/resizeDeck.js +257 -0
  17. package/dist/types/components/Button.d.ts +2 -2
  18. package/dist/types/configs/theme.d.ts +2 -0
  19. package/dist/types/embed/agentic/canvasContext.d.ts +4 -0
  20. package/dist/types/embed/agentic/canvasOperations.d.ts +3 -0
  21. package/dist/types/embed/agentic/types.d.ts +118 -0
  22. package/dist/types/embed/index.d.ts +3 -0
  23. package/dist/types/embed/render.d.ts +4 -0
  24. package/dist/types/embed/types.d.ts +3 -2
  25. package/dist/types/hooks/textCreationDefaults.d.ts +2 -0
  26. package/dist/types/hooks/useAnimationFrameCallback.d.ts +6 -0
  27. package/dist/types/hooks/useResizeDeck.d.ts +1 -0
  28. package/dist/types/i18n/cs/myna/index.d.ts +3 -0
  29. package/dist/types/i18n/en/myna/index.d.ts +3 -0
  30. package/dist/types/i18n/i18n-react.d.ts +2 -0
  31. package/dist/types/i18n/i18n-types.d.ts +2888 -1341
  32. package/dist/types/i18n/i18n-util.async.d.ts +1 -0
  33. package/dist/types/i18n/i18n-util.d.ts +1 -0
  34. package/dist/types/i18n/pl/myna/index.d.ts +3 -0
  35. package/dist/types/i18n/sk/myna/index.d.ts +3 -0
  36. package/dist/types/paint/slidePainter.d.ts +11 -0
  37. package/dist/types/store/slides.d.ts +241 -1
  38. package/dist/types/types/slides.d.ts +53 -0
  39. package/dist/types/utils/applyDesignTheme.d.ts +1 -1
  40. package/dist/types/utils/canvasFit.d.ts +17 -0
  41. package/dist/types/utils/canvasHitTest.d.ts +4 -0
  42. package/dist/types/utils/designColorRoles.d.ts +10 -0
  43. package/dist/types/utils/element.d.ts +27 -0
  44. package/dist/types/utils/elementPaint.d.ts +129 -0
  45. package/dist/types/utils/frameDomClip.d.ts +3 -0
  46. package/dist/types/utils/nestedFrames.d.ts +19 -0
  47. package/dist/types/utils/pageGuides.d.ts +6 -0
  48. package/dist/types/utils/renderMetrics.d.ts +2 -0
  49. package/dist/types/utils/resizeDeck.d.ts +11 -0
  50. package/dist/types/utils/selectInsertedElements.d.ts +2 -0
  51. package/dist/types/utils/transferPageElements.d.ts +3 -0
  52. package/dist/types/views/Editor/Canvas/MynaRulers.d.ts +17 -0
  53. package/dist/types/views/Editor/Canvas/ViewportBackground.d.ts +3 -1
  54. package/dist/types/views/Editor/Canvas/hooks/useDragElement.d.ts +2 -1
  55. package/dist/types/views/Editor/Canvas/hooks/useDrop.d.ts +1 -1
  56. package/dist/types/views/Editor/Canvas/hooks/useViewportSize.d.ts +1 -0
  57. package/dist/types/views/Editor/Canvas/index.d.ts +4 -1
  58. package/dist/types/views/Editor/EditorHeader/index.d.ts +4 -2
  59. package/dist/types/views/Editor/index.d.ts +3 -2
  60. package/dist/types/views/Myna/MynaAssetsPanel.d.ts +28 -0
  61. package/dist/types/views/Myna/MynaDownload.d.ts +4 -0
  62. package/dist/types/views/Myna/MynaDrawer.d.ts +9 -0
  63. package/dist/types/views/Myna/MynaElementsPanel.d.ts +12 -0
  64. package/dist/types/views/Myna/MynaFrameTitles.d.ts +6 -0
  65. package/dist/types/views/Myna/MynaFramesHierarchy.d.ts +1 -0
  66. package/dist/types/views/Myna/MynaFramesPanel.d.ts +6 -0
  67. package/dist/types/views/Myna/MynaHeader.d.ts +5 -0
  68. package/dist/types/views/Myna/MynaInspector.d.ts +2 -0
  69. package/dist/types/views/Myna/MynaLayersPanel.d.ts +1 -0
  70. package/dist/types/views/Myna/MynaPageCanvas.d.ts +14 -0
  71. package/dist/types/views/Myna/MynaPageLayoutControls.d.ts +1 -0
  72. package/dist/types/views/Myna/MynaPageOutline.d.ts +1 -0
  73. package/dist/types/views/Myna/MynaPageOverflow.d.ts +9 -0
  74. package/dist/types/views/Myna/MynaPagesPanel.d.ts +14 -0
  75. package/dist/types/views/Myna/MynaQrPanel.d.ts +1 -0
  76. package/dist/types/views/Myna/MynaTemplateLibrary.d.ts +3 -0
  77. package/dist/types/views/Myna/MynaViewSettings.d.ts +2 -0
  78. package/dist/types/views/Myna/MynaWorkspace.d.ts +1 -0
  79. package/dist/types/views/Myna/MynaZoomControl.d.ts +3 -0
  80. package/dist/types/views/Myna/WorkspaceLabels.d.ts +8 -0
  81. package/dist/types/views/Myna/WorkspaceObjects.d.ts +9 -0
  82. package/dist/types/views/Myna/catalog.d.ts +233 -0
  83. package/dist/types/views/Myna/exportPages.d.ts +2 -0
  84. package/dist/types/views/Myna/inspectorLabels.d.ts +30 -0
  85. package/dist/types/views/Myna/libraryMessages.d.ts +28 -0
  86. package/dist/types/views/Myna/pageLayout.d.ts +22 -0
  87. package/dist/types/views/Myna/pageSnapping.d.ts +41 -0
  88. package/dist/types/views/Myna/pdf.d.ts +10 -0
  89. package/dist/types/views/Myna/photoFrameLabels.d.ts +28 -0
  90. package/dist/types/views/Myna/photoFrameUpload.d.ts +5 -0
  91. package/dist/types/views/Myna/photoFrames.d.ts +11 -0
  92. package/dist/types/views/Myna/qrCode.d.ts +7 -0
  93. package/dist/types/views/Myna/qrMessages.d.ts +18 -0
  94. package/dist/types/views/Myna/svg.d.ts +21 -0
  95. package/dist/types/views/Myna/svgWatermark.d.ts +2 -0
  96. package/dist/types/views/Myna/templateLibrary.d.ts +26 -0
  97. package/dist/types/views/Myna/viewStore.d.ts +14 -0
  98. package/dist/types/views/Myna/workspaceLabels.d.ts +10 -0
  99. package/dist/types/views/Myna/workspaceSelectors.d.ts +17 -0
  100. package/docs/AGENTIC_BRIDGE.md +23 -0
  101. package/docs/EMBED.md +33 -0
  102. package/docs/MYNA.md +247 -0
  103. package/package.json +15 -4
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,257 @@
1
+ function bounds(el) {
2
+ if (el.type === 'line') {
3
+ const points = [el.start, el.end, el.broken, el.broken2, el.curve, ...(el.cubic ?? [])].filter((p) => !!p);
4
+ return { left: el.left + Math.min(...points.map(p => p[0])), right: el.left + Math.max(...points.map(p => p[0])), top: el.top + Math.min(...points.map(p => p[1])), bottom: el.top + Math.max(...points.map(p => p[1])) };
5
+ }
6
+ const angle = (el.rotate ?? 0) * Math.PI / 180;
7
+ const w = Math.abs(el.width * Math.cos(angle)) + Math.abs(el.height * Math.sin(angle));
8
+ const h = Math.abs(el.width * Math.sin(angle)) + Math.abs(el.height * Math.cos(angle));
9
+ return { left: el.left + (el.width - w) / 2, right: el.left + (el.width + w) / 2, top: el.top + (el.height - h) / 2, bottom: el.top + (el.height + h) / 2 };
10
+ }
11
+ function union(a, b) {
12
+ return { left: Math.min(a.left, b.left), right: Math.max(a.right, b.right), top: Math.min(a.top, b.top), bottom: Math.max(a.bottom, b.bottom) };
13
+ }
14
+ function isBackdrop(el, canvas) {
15
+ return el.type === 'shape' && !el.text && !el.rotate && !el.fixedRatio && el.left <= 1 && el.top <= 1 && el.width >= canvas.width - 2 && el.height >= canvas.height - 2;
16
+ }
17
+ function isDecor(el, canvas) {
18
+ return el.type === 'shape' && !el.text && !el.groupId && (el.name === 'Decor' || el.left < -1 || el.top < -1 || el.left + el.width > canvas.width + 1 || el.top + el.height > canvas.height + 1);
19
+ }
20
+ function edgeBand(el, canvas) {
21
+ if (el.type !== 'shape' || el.text || el.groupId || el.rotate || el.fixedRatio)
22
+ return;
23
+ if (Math.abs(el.top) <= 1 && Math.abs(el.height - canvas.height) <= 2 && el.width < canvas.width * 0.3
24
+ && (Math.abs(el.left) <= 1 || Math.abs(el.left + el.width - canvas.width) <= 1))
25
+ return 'vertical';
26
+ if (Math.abs(el.left) <= 1 && Math.abs(el.width - canvas.width) <= 2 && el.height < canvas.height * 0.2
27
+ && (Math.abs(el.top) <= 1 || Math.abs(el.top + el.height - canvas.height) <= 1))
28
+ return 'horizontal';
29
+ }
30
+ /** Piecewise affine map: occupied tracks retain their scale; only empty gutters expand.
31
+ * Group bounds occupy a single track, so labels never detach from their diagram.
32
+ */
33
+ function axisTracks(intervals, source) {
34
+ const merged = [];
35
+ for (const [start, end] of intervals.sort((a, b) => a[0] - b[0])) {
36
+ const lo = Math.max(0, start), hi = Math.min(source, end);
37
+ if (hi <= lo)
38
+ continue;
39
+ const last = merged.at(-1);
40
+ if (last && lo <= last[1] + 1)
41
+ last[1] = Math.max(last[1], hi);
42
+ else
43
+ merged.push([lo, hi]);
44
+ }
45
+ const gaps = [];
46
+ let cursor = 0;
47
+ for (const [lo, hi] of merged) {
48
+ if (lo > cursor)
49
+ gaps.push([cursor, lo]);
50
+ cursor = hi;
51
+ }
52
+ if (cursor < source)
53
+ gaps.push([cursor, source]);
54
+ const free = gaps.reduce((sum, [lo, hi]) => sum + hi - lo, 0);
55
+ return { gaps, free };
56
+ }
57
+ function axisMap(intervals, source, target, scale) {
58
+ const { gaps, free } = axisTracks(intervals, source);
59
+ const extra = target - source * scale;
60
+ return (position) => position * scale + (free > 0
61
+ ? extra * gaps.reduce((sum, [lo, hi]) => sum + Math.max(0, Math.min(position, hi) - lo), 0) / free
62
+ : extra / 2);
63
+ }
64
+ /** Recognize a full-width heading above independent body columns. Each column
65
+ * gets its own vertical tracks; a long item in the left column cannot prevent
66
+ * the right column from distributing its rows through the available height.
67
+ */
68
+ function bodyColumns(boxes, from) {
69
+ if (boxes.length < 3)
70
+ return;
71
+ const top = Math.min(...boxes.map(b => b.top));
72
+ const headers = boxes.filter(b => Math.abs(b.top - top) < 1 && b.right - b.left >= from.width * 0.55 && b.bottom <= from.height * 0.26);
73
+ if (!headers.length)
74
+ return;
75
+ const headerBottom = Math.max(...headers.map(b => b.bottom));
76
+ const body = boxes.filter(b => !headers.includes(b));
77
+ if (body.some(b => b.top < headerBottom))
78
+ return;
79
+ const bodyTop = Math.min(...body.map(b => b.top));
80
+ const ranges = [];
81
+ for (const box of [...body].sort((a, b) => a.left - b.left)) {
82
+ const last = ranges.at(-1);
83
+ if (last && box.left <= last.right + from.width * 0.025) {
84
+ last.right = Math.max(last.right, box.right);
85
+ last.boxes.push(box);
86
+ }
87
+ else
88
+ ranges.push({ left: box.left, right: box.right, boxes: [box] });
89
+ }
90
+ if (ranges.length > 4)
91
+ return;
92
+ const margin = Math.min(from.height * 0.06, Math.max(top, from.height * 0.03));
93
+ const columns = ranges.map(range => {
94
+ const height = Math.max(...range.boxes.map(b => b.bottom)) - bodyTop;
95
+ const intervals = range.boxes.map(b => [b.top - bodyTop, b.bottom - bodyTop]);
96
+ const { free } = axisTracks(intervals, height);
97
+ return { ...range, height, intervals, minHeight: height - free + Math.min(free, height * 0.08) };
98
+ });
99
+ return { bodyTop, margin, columns, minHeight: bodyTop + margin + Math.max(...columns.map(c => c.minHeight)) };
100
+ }
101
+ function scalePixels(html, scale) {
102
+ // CSS lengths only: do not rewrite lesson text containing quantities in px.
103
+ return html.replace(/style=(['"])(.*?)\1/gi, (_, quote, css) => `style=${quote}${css.replace(/(-?\d+(?:\.\d+)?)px\b/g, (_m, n) => `${Number((Number(n) * scale).toFixed(4))}px`)}${quote}`);
104
+ }
105
+ function scaleNumber(record, key, scale) {
106
+ const obj = record;
107
+ if (typeof obj[key] === 'number')
108
+ obj[key] = obj[key] * scale;
109
+ }
110
+ function scaleTypography(el, scale) {
111
+ if (scale === 1)
112
+ return;
113
+ const text = el.type === 'text' ? el : el.type === 'shape' ? el.text : undefined;
114
+ if (text) {
115
+ text.content = scalePixels(text.content, scale);
116
+ text.inset = (text.inset ?? [10, 10, 10, 10]).map(v => v * scale);
117
+ text.paragraphSpace = (text.paragraphSpace ?? 5);
118
+ for (const key of ['wordSpace', 'paragraphSpace', 'placeholderFontSize', 'placeholderLayoutHeight'])
119
+ scaleNumber(text, key, scale);
120
+ if (el.type === 'text' && el.structuredText) {
121
+ // HTML is the source of truth; discard the stale import cache.
122
+ delete el.structuredText;
123
+ }
124
+ }
125
+ if (el.type === 'table') {
126
+ el.cellMinHeight *= scale;
127
+ for (const row of el.data)
128
+ for (const cell of row) {
129
+ cell.text = scalePixels(cell.text, scale);
130
+ if (cell.style?.fontsize)
131
+ cell.style.fontsize = cell.style.fontsize.replace(/^(\d+(?:\.\d+)?)(px|pt)$/i, (_, value, unit) => `${Number(value) * scale}${unit}`);
132
+ }
133
+ }
134
+ if (el.type === 'chart')
135
+ el.options = { ...el.options, fontSize: (el.options?.fontSize ?? 12) * scale };
136
+ if (el.type === 'code')
137
+ el.fontSize *= scale;
138
+ if (el.type === 'latex')
139
+ el.strokeWidth *= scale;
140
+ if ('outline' in el && el.outline)
141
+ scaleNumber(el.outline, 'width', scale);
142
+ if ('shadow' in el && el.shadow)
143
+ for (const key of ['h', 'v', 'blur'])
144
+ scaleNumber(el.shadow, key, scale);
145
+ }
146
+ /** Resize a deck without distorting media or changing reading order.
147
+ * Uniformly scale content and typography, redistribute available space through
148
+ * empty tracks, and keep decorative edge shapes attached to their canvas edge.
149
+ * Overlaps, rotations, z-order and grouped compositions remain intact.
150
+ */
151
+ export function resizeDeckSlides(slides, from, to) {
152
+ for (const n of [from.width, from.height, to.width, to.height]) {
153
+ if (!Number.isFinite(n) || n <= 0)
154
+ throw new Error('Canvas dimensions must be finite and positive.');
155
+ }
156
+ const result = structuredClone(slides);
157
+ if (from.width === to.width && from.height === to.height)
158
+ return result;
159
+ for (const slide of result) {
160
+ // Guides describe page coordinates; resize them proportionally along their own axis.
161
+ if (slide.guides)
162
+ slide.guides = slide.guides.map(guide => ({ ...guide,
163
+ position: guide.position * (guide.axis === 'x' ? to.width / from.width : to.height / from.height),
164
+ }));
165
+ const groups = new Map();
166
+ for (const el of slide.elements) {
167
+ if ((el.type === 'line' && !el.groupId) || isBackdrop(el, from) || isDecor(el, from) || edgeBand(el, from))
168
+ continue;
169
+ const key = el.groupId ?? el.id, box = bounds(el);
170
+ groups.set(key, groups.has(key) ? union(groups.get(key), box) : box);
171
+ }
172
+ const boxes = [...groups.values()];
173
+ const vertical = boxes.map(b => [b.top, b.bottom]);
174
+ const { free } = axisTracks(vertical, from.height);
175
+ // Width sets the preferred type size. Consume spare vertical gutters before
176
+ // shrinking text; reversing a ratio change should not progressively shrink it.
177
+ const minHeight = from.height - free + Math.min(free, from.height * 0.08);
178
+ const body = bodyColumns(boxes, from);
179
+ const scale = Math.min(to.width / from.width, to.height / Math.max(1, body?.minHeight ?? minHeight));
180
+ const x = axisMap(boxes.map(b => [b.left, b.right]), from.width, to.width, scale);
181
+ const y = axisMap(boxes.map(b => [b.top, b.bottom]), from.height, to.height, scale);
182
+ const columnMaps = body?.columns.map(column => ({ ...column,
183
+ map: axisMap(column.intervals, column.height, Math.max(1, to.height - (body.bodyTop + body.margin) * scale), scale),
184
+ }));
185
+ const mapY = (px, py) => {
186
+ if (!body || !columnMaps)
187
+ return y(py);
188
+ if (py < body.bodyTop - 1)
189
+ return py * scale;
190
+ const column = columnMaps.find(c => px >= c.left - 1 && px <= c.right + 1);
191
+ return column ? body.bodyTop * scale + column.map(py - body.bodyTop) : y(py);
192
+ };
193
+ for (const el of slide.elements) {
194
+ if (el.type === 'shape' && isBackdrop(el, from)) {
195
+ el.left = 0;
196
+ el.top = 0;
197
+ el.width = to.width;
198
+ el.height = to.height;
199
+ continue;
200
+ }
201
+ const band = edgeBand(el, from);
202
+ if (el.type === 'shape' && band) {
203
+ if (band === 'vertical') {
204
+ el.width *= scale;
205
+ el.height = to.height;
206
+ el.top = 0;
207
+ el.left = el.left < from.width / 2 ? 0 : to.width - el.width;
208
+ }
209
+ else {
210
+ el.height *= scale;
211
+ el.width = to.width;
212
+ el.left = 0;
213
+ el.top = el.top < from.height / 2 ? 0 : to.height - el.height;
214
+ }
215
+ scaleTypography(el, scale);
216
+ continue;
217
+ }
218
+ const left = el.left, top = el.top;
219
+ if (el.type === 'line') {
220
+ // Remap connector geometry with the same tracks as its attached objects.
221
+ const group = el.groupId ? groups.get(el.groupId) : undefined;
222
+ const lineX = group ? (v) => x(group.left) + (v - group.left) * scale : x;
223
+ const lineY = group ? (_px, v) => mapY(group.left, group.top) + (v - group.top) * scale : mapY;
224
+ el.left = lineX(left);
225
+ el.top = lineY(left, top);
226
+ el.width *= scale;
227
+ const point = (p) => [lineX(left + p[0]) - el.left, lineY(left + p[0], top + p[1]) - el.top];
228
+ el.start = point(el.start);
229
+ el.end = point(el.end);
230
+ if (el.broken)
231
+ el.broken = point(el.broken);
232
+ if (el.broken2)
233
+ el.broken2 = point(el.broken2);
234
+ if (el.curve)
235
+ el.curve = point(el.curve);
236
+ if (el.cubic)
237
+ el.cubic = [point(el.cubic[0]), point(el.cubic[1])];
238
+ }
239
+ else if (isDecor(el, from)) {
240
+ const cx = left + el.width / 2, cy = top + el.height / 2;
241
+ el.left = cx > from.width / 2 ? to.width - (from.width - left) * scale : left * scale;
242
+ el.top = cy > from.height / 2 ? to.height - (from.height - top) * scale : top * scale;
243
+ el.width *= scale;
244
+ el.height *= scale;
245
+ }
246
+ else {
247
+ const box = groups.get(el.groupId ?? el.id);
248
+ el.left = x(box.left) + (left - box.left) * scale;
249
+ el.top = mapY(box.left, box.top) + (top - box.top) * scale;
250
+ el.width *= scale;
251
+ el.height *= scale;
252
+ }
253
+ scaleTypography(el, scale);
254
+ }
255
+ }
256
+ return result;
257
+ }
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import type { ReactNode, MouseEvent } from 'react';
2
2
  export type IButtonProps = {
3
3
  checked?: boolean;
4
4
  disabled?: boolean;
@@ -6,7 +6,7 @@ export type IButtonProps = {
6
6
  size?: 'small' | 'normal';
7
7
  first?: boolean;
8
8
  last?: boolean;
9
- onClick?: () => void;
9
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
10
10
  children?: ReactNode;
11
11
  style?: React.CSSProperties;
12
12
  className?: string;
@@ -7,6 +7,8 @@ export interface PresetTheme {
7
7
  background: string;
8
8
  fontColor: string;
9
9
  featureFontColor?: string;
10
+ /** Retain pale panels and accent roles when restyling host-authored decks. */
11
+ preserveColorRoles?: boolean;
10
12
  fontname: string;
11
13
  colors: string[];
12
14
  /** Series palette when `colors` includes near-background swatches (Ink #171717). */
@@ -0,0 +1,4 @@
1
+ import type { Slide } from '../../types/slides';
2
+ import type { FikaCanvasContext, FikaCanvasReadOptions } from './types';
3
+ /** Bounded summaries never contain image data, SVG paths, or full rich-text HTML. */
4
+ export declare function summarizeCanvas(slides: Slide[], activePageId: string | undefined, selectedIds: string[], width: number, ratio: number, options?: FikaCanvasReadOptions): FikaCanvasContext;
@@ -0,0 +1,3 @@
1
+ import type { FikaAgentCommand, FikaCanvasOperation } from './types';
2
+ /** Expand concise canvas operations into the existing validated native handlers. */
3
+ export declare function canvasOperationCommand(operation: FikaCanvasOperation): FikaAgentCommand;
@@ -1205,7 +1205,123 @@ export interface FikaAgentApi {
1205
1205
  import: FikaAgentImportApi;
1206
1206
  export: FikaAgentExportApi;
1207
1207
  }
1208
+ export type FikaCanvasOperation = {
1209
+ op: 'title';
1210
+ title: string;
1211
+ } | {
1212
+ op: 'viewport';
1213
+ width: number;
1214
+ height: number;
1215
+ } | {
1216
+ op: 'page';
1217
+ id?: string;
1218
+ name?: string;
1219
+ x?: number;
1220
+ y?: number;
1221
+ background?: string;
1222
+ } | {
1223
+ op: 'pageUpdate';
1224
+ id: string;
1225
+ patch: Partial<Slide>;
1226
+ } | {
1227
+ op: 'text';
1228
+ pageId?: string;
1229
+ id?: string;
1230
+ x: number;
1231
+ y: number;
1232
+ width: number;
1233
+ height: number;
1234
+ text: string;
1235
+ fontSize?: number;
1236
+ fontName?: string;
1237
+ color?: string;
1238
+ bold?: boolean;
1239
+ align?: 'left' | 'center' | 'right' | 'justify';
1240
+ } | {
1241
+ op: 'textUpdate';
1242
+ pageId?: string;
1243
+ id: string;
1244
+ text: string;
1245
+ style?: TextRunStyle;
1246
+ } | {
1247
+ op: 'shape';
1248
+ pageId?: string;
1249
+ id?: string;
1250
+ x: number;
1251
+ y: number;
1252
+ width: number;
1253
+ height: number;
1254
+ shape: 'rect' | 'ellipse';
1255
+ fill?: string;
1256
+ } | {
1257
+ op: 'element';
1258
+ pageId?: string;
1259
+ element: Partial<PPTElement> & {
1260
+ type: PPTElement['type'];
1261
+ };
1262
+ } | {
1263
+ op: 'update';
1264
+ pageId?: string;
1265
+ id: string;
1266
+ patch: Partial<PPTElement>;
1267
+ } | {
1268
+ op: 'remove';
1269
+ pageId?: string;
1270
+ id: string;
1271
+ };
1272
+ export interface FikaCanvasApplyResult {
1273
+ results: Array<{
1274
+ op: FikaCanvasOperation['op'];
1275
+ id?: string;
1276
+ pageId?: string;
1277
+ }>;
1278
+ }
1279
+ export interface FikaCanvasReadOptions {
1280
+ pageId?: string;
1281
+ offset?: number;
1282
+ limit?: number;
1283
+ textLimit?: number;
1284
+ }
1285
+ export interface FikaCanvasContext {
1286
+ viewport: {
1287
+ width: number;
1288
+ height: number;
1289
+ };
1290
+ activePageId?: string;
1291
+ selectedIds: string[];
1292
+ pageCount: number;
1293
+ pages: Array<{
1294
+ id: string;
1295
+ name?: string;
1296
+ x: number;
1297
+ y: number;
1298
+ elementCount: number;
1299
+ }>;
1300
+ pageId?: string;
1301
+ elementCount: number;
1302
+ offset: number;
1303
+ nextOffset?: number;
1304
+ elements: Array<{
1305
+ id: string;
1306
+ type: string;
1307
+ name?: string;
1308
+ x: number;
1309
+ y: number;
1310
+ width: number;
1311
+ height?: number;
1312
+ parentFrameId?: string;
1313
+ groupId?: string;
1314
+ frame?: {
1315
+ clipContent: boolean;
1316
+ };
1317
+ text?: string;
1318
+ }>;
1319
+ }
1208
1320
  export interface FikaCommandPayloadMap {
1321
+ 'canvas.get': FikaCanvasReadOptions | undefined;
1322
+ 'canvas.apply': {
1323
+ operations: FikaCanvasOperation[];
1324
+ };
1209
1325
  'deck.get': undefined;
1210
1326
  'deck.set': FikaDeckInput | FikaDocument;
1211
1327
  'deck.patch': FikaDeckPatch | Partial<FikaDocument>;
@@ -1902,6 +2018,8 @@ export interface FikaCommandPayloadMap {
1902
2018
  'view.exitPresentation': undefined;
1903
2019
  }
1904
2020
  export interface FikaCommandResultDataMap {
2021
+ 'canvas.get': FikaCanvasContext;
2022
+ 'canvas.apply': FikaCanvasApplyResult;
1905
2023
  'deck.get': FikaDeckDocument;
1906
2024
  'deck.set': FikaDeckDocument;
1907
2025
  'deck.patch': FikaDeckDocument;
@@ -12,3 +12,6 @@ export type { Locales as FikaLocales } from '../i18n/locale';
12
12
  export type { ChartData, ChartOptions, ChartType, Note, NoteReply, PPTAnimation, PPTAudioElement, PPTChartElement, PPTElement, PPTElementLink, PPTImageElement, PPTLatexElement, PPTLineElement, PPTShapeElement, PPTTableElement, PPTTextElement, PPTVideoElement, ShapeText, Slide, SlideBackground, SlideTemplate, SlideTheme, TableCell, TableCellStyle, TextAlign, TurningMode, } from '../types/slides';
13
13
  export type { FikaDesignTheme } from '../configs/designThemes';
14
14
  export { getFikaDefaultDesignThemes } from '../configs/designThemes';
15
+ export { resizeDeckSlides, type SlideCanvas } from '../utils/resizeDeck';
16
+ /** Myna design-mode capabilities and editable starter document. */
17
+ export { createMynaDocument, MYNA_FORMATS } from '../views/Myna/catalog';
@@ -21,6 +21,10 @@ export interface FikaRenderSlideOptions {
21
21
  format?: 'image/png' | 'image/jpeg' | 'image/webp';
22
22
  /** Encoder quality for lossy formats (0–1). Default 0.9. */
23
23
  quality?: number;
24
+ /** Omit the page background for PNG/WebP without changing element colors. */
25
+ transparentBackground?: boolean;
26
+ /** Load original image pixels, using the host media resolver if needed. Fail if an image cannot load. */
27
+ fullResolutionImages?: boolean;
24
28
  }
25
29
  export interface FikaDeckAtlasOptions extends Omit<FikaRenderSlideOptions, 'width'> {
26
30
  /** Width of one slide tile in CSS px. Default 640. */
@@ -61,8 +61,8 @@ export interface FikaHeaderMenuItem {
61
61
  /** Fired when the entry is clicked (the dropdown closes first). */
62
62
  onSelect?: (id: string) => void;
63
63
  }
64
- /** `editor` is the default full editor; `presentation` boots straight into the fullscreen slideshow with no editor chrome. */
65
- export type FikaViewMode = 'editor' | 'presentation';
64
+ /** `editor`: presentation editor; `presentation`: viewer; `canva` (alias `myna`): Myna design workspace. */
65
+ export type FikaViewMode = 'editor' | 'presentation' | 'canva' | 'myna';
66
66
  export interface FikaMountOptions {
67
67
  /** Replacement design catalog in display order. Omit for Fika defaults; [] hides presets. Does not restyle the loaded document. */
68
68
  designThemes?: readonly FikaDesignTheme[];
@@ -135,6 +135,7 @@ export interface FikaMountOptions {
135
135
  */
136
136
  openPanelOnTextSelection?: boolean;
137
137
  /**
138
+ * `canva` (or `myna`) mounts the Myna graphic design workspace.
138
139
  * `presentation` mounts a presentation-only viewer: once the deck resolves,
139
140
  * the fullscreen slideshow starts immediately and the editor never renders.
140
141
  * Exiting the slideshow re-enters it, so the page stays a pure viewer.
@@ -0,0 +1,2 @@
1
+ /** Creation policy only; existing and imported text retains its authored sizing. */
2
+ export declare const FixedTextCreationContext: import("react").Context<boolean>;
@@ -0,0 +1,6 @@
1
+ /** Coalesce transient pointer input, with an explicit flush at the transaction boundary. */
2
+ export declare function useAnimationFrameCallback<T>(callback: (value: T) => void): {
3
+ schedule: (value: T) => void;
4
+ flush: () => void;
5
+ cancel: () => void;
6
+ };
@@ -0,0 +1 @@
1
+ export default function useResizeDeck(): (width: number, height: number) => void;
@@ -0,0 +1,3 @@
1
+ import type { NamespaceMynaTranslation } from '../../i18n-types';
2
+ declare const myna: NamespaceMynaTranslation;
3
+ export default myna;
@@ -0,0 +1,3 @@
1
+ import type { BaseTranslation } from '../../i18n-types';
2
+ declare const myna: BaseTranslation;
3
+ export default myna;
@@ -1,6 +1,7 @@
1
1
  import type { Locales, TranslationFunctions } from './i18n-types';
2
2
  declare const TypesafeI18n: import("react").FunctionComponent<import("typesafe-i18n/react").TypesafeI18nProps<Locales>>, I18nContext: import("react").Context<import("typesafe-i18n/react").I18nContextType<Locales, {
3
3
  screen: import("./i18n-types").NamespaceScreenTranslation;
4
+ myna: import("./i18n-types").NamespaceMynaTranslation;
4
5
  export: import("./i18n-types").NamespaceExportTranslation;
5
6
  editor: import("./i18n-types").NamespaceEditorTranslation;
6
7
  mobile: import("./i18n-types").NamespaceMobileTranslation;
@@ -12,6 +13,7 @@ declare const TypesafeI18n: import("react").FunctionComponent<import("typesafe-i
12
13
  export { TypesafeI18n, I18nContext };
13
14
  export declare function useI18nContext(): import("typesafe-i18n/react").I18nContextType<Locales, {
14
15
  screen: import("./i18n-types").NamespaceScreenTranslation;
16
+ myna: import("./i18n-types").NamespaceMynaTranslation;
15
17
  export: import("./i18n-types").NamespaceExportTranslation;
16
18
  editor: import("./i18n-types").NamespaceEditorTranslation;
17
19
  mobile: import("./i18n-types").NamespaceMobileTranslation;