fika-editor 3.0.37 → 3.0.39

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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Geometry of a skeleton slide (`Slide.skeleton`): grey blocks standing in for
3
+ * a title, a few lines of body and a picture panel. Fractions of the slide
4
+ * box so the same shapes paint on the rail thumbnail, the live canvas and an
5
+ * offscreen `renderSlide`.
6
+ */
7
+ export type SlideSkeletonBlock = {
8
+ x: number;
9
+ y: number;
10
+ w: number;
11
+ h: number;
12
+ };
13
+ export declare const SLIDE_SKELETON_BLOCKS: readonly SlideSkeletonBlock[];
14
+ /** Block fill; kept translucent so a themed slide background still reads through. */
15
+ export declare const SLIDE_SKELETON_FILL = "rgba(30, 41, 59, 0.09)";
16
+ /** Corner radius as a fraction of the slide width. */
17
+ export declare const SLIDE_SKELETON_RADIUS = 0.008;
@@ -5,9 +5,16 @@ export declare const getMermaidRaster: (element: PPTMermaidElement, invalidate:
5
5
  export declare const getCodeRaster: (element: PPTCodeElement, invalidate: () => void) => Raster | undefined;
6
6
  /**
7
7
  * MathLive typeset of a formula element, mirroring `LatexContent`'s DOM
8
- * (flex-centered box, 36px stage scaled uniformly into the authored box).
8
+ * (flex-centered box, a 36px stage fitted uniformly into the authored box).
9
9
  * html-to-image is used instead of a bare foreignObject because SVG-as-image
10
10
  * cannot load the MathLive web fonts.
11
+ *
12
+ * The fit is applied as a font size, not a CSS transform: inside the SVG
13
+ * snapshot, box edges (the radical rule, fraction bars) snap to whole CSS
14
+ * pixels of the pre-transform layout while glyphs scale exactly, so a scaled
15
+ * 36px stage paints a `\sqrt` rule thinner and lower than the surd's tick.
16
+ * Laying out at the final size keeps that snap error under half a pixel, and
17
+ * the 2x capture halves it again.
11
18
  */
12
19
  export declare const getLatexRaster: (element: PPTLatexElement, invalidate: () => void) => Raster | undefined;
13
20
  /**
@@ -861,6 +861,7 @@ export declare const useSlidesStore: import("zustand").UseBoundStore<Omit<import
861
861
  };
862
862
  type?: import("../types/slides").SlideType;
863
863
  sourcePackageId?: string;
864
+ skeleton?: boolean;
864
865
  }[];
865
866
  slideIndex: number;
866
867
  viewportSize: number;
@@ -1643,6 +1644,7 @@ export declare const useSlidesStore: import("zustand").UseBoundStore<Omit<import
1643
1644
  };
1644
1645
  type?: import("../types/slides").SlideType;
1645
1646
  sourcePackageId?: string;
1647
+ skeleton?: boolean;
1646
1648
  }[];
1647
1649
  theme: {
1648
1650
  backgroundColor?: string;
@@ -2480,6 +2482,7 @@ export declare const useSlidesStore: import("zustand").UseBoundStore<Omit<import
2480
2482
  };
2481
2483
  type?: import("../types/slides").SlideType;
2482
2484
  sourcePackageId?: string;
2485
+ skeleton?: boolean;
2483
2486
  }[];
2484
2487
  slideIndex: number;
2485
2488
  viewportSize: number;
@@ -3262,6 +3265,7 @@ export declare const useSlidesStore: import("zustand").UseBoundStore<Omit<import
3262
3265
  };
3263
3266
  type?: import("../types/slides").SlideType;
3264
3267
  sourcePackageId?: string;
3268
+ skeleton?: boolean;
3265
3269
  }[];
3266
3270
  theme: {
3267
3271
  backgroundColor?: string;
@@ -543,6 +543,10 @@ export type SlideType = 'cover' | 'contents' | 'transition' | 'content' | 'end';
543
543
  * remark?: speaker notes
544
544
  * turningMode?: transition
545
545
  * sourcePackageId?: retained PPTX package id (when imported from Office)
546
+ * skeleton?: the slide is a placeholder whose content is still being produced
547
+ * (a host streaming a deck in). Painted as shimmering blocks in the rail and
548
+ * on the canvas, not editable; cleared by the first `slides.update` that
549
+ * omits or falsifies it.
546
550
  */
547
551
  export interface Slide {
548
552
  id: string;
@@ -555,6 +559,7 @@ export interface Slide {
555
559
  sectionTag?: SectionTag;
556
560
  type?: SlideType;
557
561
  sourcePackageId?: string;
562
+ skeleton?: boolean;
558
563
  }
559
564
  /**
560
565
  * Slide theme (background, accent colors, default font).
@@ -1,5 +1,5 @@
1
1
  import type { Slide } from '../types/slides';
2
- export type PaintedSlide = Pick<Slide, 'id' | 'elements' | 'background' | 'type'>;
2
+ export type PaintedSlide = Pick<Slide, 'id' | 'elements' | 'background' | 'type' | 'skeleton'>;
3
3
  export type PaintedSlideDiff = {
4
4
  added: string[];
5
5
  removed: string[];
@@ -0,0 +1,12 @@
1
+ export type ISlideSkeletonProps = {
2
+ className?: string;
3
+ /** Swallow pointer gestures so the placeholder cannot be drawn on (live canvas). */
4
+ shield?: boolean;
5
+ };
6
+ /**
7
+ * Shimmering placeholder painted over a `Slide.skeleton` slide. Absolutely
8
+ * fills its positioned parent; block geometry is shared with the canvas
9
+ * painter so a thumbnail and a `renderSlide` capture agree.
10
+ */
11
+ declare const SlideSkeleton: import("react").MemoExoticComponent<({ className, shield }: ISlideSkeletonProps) => import("react").JSX.Element>;
12
+ export default SlideSkeleton;
package/docs/EMBED.md CHANGED
@@ -148,6 +148,21 @@ if (createTitle.ok && createTitle.data) {
148
148
  await controller.slides.setRemark(createSlide.data.id, '<p>Teacher notes from the sciobot agent</p>')
149
149
  ```
150
150
 
151
+ ### Skeleton slides (streaming a deck in)
152
+
153
+ A slide with `skeleton: true` is a placeholder for content that is still being produced. The rail thumbnail and the live canvas paint shimmering grey blocks over its background, the canvas refuses edits on it, and `renderSlide` paints the same blocks statically. Seed the whole deck up front with the ids you will later fill, then swap each one in place — a `slides.update` patch that carries `elements` (or `skeleton: false`) clears the flag:
154
+
155
+ ```ts
156
+ await controller.setDocument({
157
+ title,
158
+ slides: outline.map(item => ({ id: item.id, elements: [], skeleton: true, background })),
159
+ })
160
+
161
+ // …as each slide finishes generating:
162
+ await controller.slides.update(item.id, { elements, background, remark })
163
+ controller.goToSlide(item.id)
164
+ ```
165
+
151
166
  ### Bridge subscriptions
152
167
 
153
168
  Subscribe once when the controller is mounted, then unsubscribe before replacing or destroying it. `documentChanged` is the best signal for persistence, while `commandFailed` is the best signal for agent telemetry:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fika-editor",
3
- "version": "3.0.37",
3
+ "version": "3.0.39",
4
4
  "description": "Fika presentation editor embed bundle with a typed agentic bridge.",
5
5
  "type": "module",
6
6
  "main": "dist/embed/fika-embed.js",
@@ -109,7 +109,7 @@
109
109
  "lucide-react": "^1.33.0",
110
110
  "markdown-it": "^15.0.0",
111
111
  "markdown-it-texmath": "^1.0.0",
112
- "mathlive": "npm:@lofcz/mathlive@^0.110.8",
112
+ "mathlive": "npm:@lofcz/mathlive@^0.110.9",
113
113
  "mathml2omml-plus": "^0.6.4",
114
114
  "mermaid": "^11.17.0",
115
115
  "mitt": "^3.0.1",