@bendyline/squisq-react 2.3.3 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -116,6 +116,13 @@ interface UseDocPlaybackOptions {
116
116
  theme?: Theme;
117
117
  /** Host seek callback used by block navigation actions. */
118
118
  onSeek?: (time: number) => void;
119
+ /**
120
+ * Whether real audio-segment timing should reshape the authored block
121
+ * sequence. Synthetic preview tracks are only a playback clock; treating
122
+ * them as narration can merge short authored slides to satisfy narration
123
+ * pacing rules.
124
+ */
125
+ useAudioSegmentTiming?: boolean;
119
126
  }
120
127
  declare function useDocPlayback(script: Doc | null, currentTime: number, options?: UseDocPlaybackOptions): PlaybackState & PlaybackActions;
121
128
 
@@ -6,7 +6,7 @@ import {
6
6
  useDocPlayback,
7
7
  useMediaSchedule,
8
8
  useViewportOrientation
9
- } from "../chunk-NWZQGZIJ.js";
9
+ } from "../chunk-BOZJ655L.js";
10
10
  import {
11
11
  useAutoSurface
12
12
  } from "../chunk-TT6ENR6T.js";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { SquisqRenderAPI } from './player/index.js';
1
+ import { SquisqRenderAPI, VideoPresentation as VideoPresentation$1, PipSize, PipShape, PipPosition } from './player/index.js';
2
2
  export { BlockMarker, BlockRenderer, CaptionMode, CaptionOverlay, CaptionStyle, ControlsLayout, DisplayMode, DocControlsBottom, DocControlsOverlay, DocControlsSidebar, DocControlsSlideshow, DocPlayer, DocPlayerProps, DocPlayerWithSidebar, DocProgressBar, InlineAudioPlayer, InlineAudioPlayerProps, InlineVideoPlayer, InlineVideoPlayerProps, MediaClipLayer, MediaClipLayerProps, PlaybackActions, PlaybackState, RenderAudioSegmentInfo, RenderBlockInfo, RenderCaptionInfo, RenderChapterInfo, SlideNavActions, SocialCaptionOverlay, formatTime } from './player/index.js';
3
- import { Theme } from '@bendyline/squisq/schemas';
3
+ import { Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, ScheduledClip, MediaProvider } from '@bendyline/squisq/schemas';
4
4
  export { MarkdownRenderer, MermaidDiagram, MermaidDiagramProps } from './markdown/index.js';
5
5
  export { CanvasSection, CanvasSectionProps, ImageDisplayMode, LinearDocView, LinearDocViewProps, PageSectionView, PageSectionViewProps, PageViewContext, PageViewContextValue, usePageView } from './page/index.js';
6
6
  export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TableLayer, TextLayer, TreeLayer, VideoLayer } from './layers/index.js';
@@ -9,8 +9,8 @@ export { A as AudioActions, a as AudioController, b as AudioState } from './Audi
9
9
  export { getAnimationStyle, getTransitionClass } from '@bendyline/squisq/doc';
10
10
  export { JsonView, JsonViewProps } from './json-view/index.js';
11
11
  import 'react/jsx-runtime';
12
- import '@bendyline/squisq/markdown';
13
12
  import 'react';
13
+ import '@bendyline/squisq/markdown';
14
14
  import '@bendyline/squisq/jsonForm';
15
15
 
16
16
  /**
@@ -54,6 +54,14 @@ interface MountOptions {
54
54
  audio?: Record<string, string>;
55
55
  /** Optional theme override */
56
56
  theme?: Theme;
57
+ /** Player-level video placement override. Omitted values resolve from the Doc. */
58
+ videoPresentation?: VideoPresentation;
59
+ /** Picture-in-picture size override. Omitted values resolve from the Doc. */
60
+ pipSize?: VideoPipSize;
61
+ /** Picture-in-picture shape override. Omitted values resolve from the Doc. */
62
+ pipShape?: VideoPipShape;
63
+ /** Picture-in-picture corner override. Omitted values resolve from the Doc. */
64
+ pipPosition?: VideoPipPosition;
57
65
  /** Auto-play on mount (only for slideshow mode, default: false) */
58
66
  autoPlay?: boolean;
59
67
  /**
@@ -87,4 +95,48 @@ interface SquisqPlayerHandle {
87
95
  unmount(): void;
88
96
  }
89
97
 
90
- export { type MountOptions, type SquisqPlayerHandle, SquisqRenderAPI };
98
+ interface DocPlayerAppearanceOverrides {
99
+ theme?: Theme;
100
+ videoPresentation?: VideoPresentation$1;
101
+ pipSize?: PipSize;
102
+ pipShape?: PipShape;
103
+ pipPosition?: PipPosition;
104
+ showCoverSlide?: boolean;
105
+ }
106
+ interface ResolvedDocPlayerAppearance {
107
+ theme: Theme;
108
+ videoPresentation: VideoPresentation$1;
109
+ pipSize: PipSize;
110
+ pipShape: PipShape;
111
+ pipPosition: PipPosition;
112
+ showCoverSlide: boolean;
113
+ }
114
+ /** Resolve the visual settings a standalone/export player must inherit from its Doc. */
115
+ declare function resolveDocPlayerAppearance(doc: Doc, overrides?: DocPlayerAppearanceOverrides): ResolvedDocPlayerAppearance;
116
+
117
+ /**
118
+ * useMediaClipDurations
119
+ *
120
+ * Probes the intrinsic (natural) duration of scheduled video clips so the media
121
+ * schedule can end an unlocked video at its own length instead of holding its
122
+ * last frame until the timeline ends. Returns a `Map<src, seconds>` keyed by the
123
+ * clip's raw `src`, suitable for {@link resolveMediaSchedule}'s
124
+ * `intrinsicDuration` option.
125
+ *
126
+ * A media file's real length is not part of the pure `Doc` model, so it can only
127
+ * be learned in the browser. This hook mirrors {@link useMediaUrl}'s resolution
128
+ * (MediaProvider → basePath fallback, resource-policy gated), loads metadata from
129
+ * a throwaway `<video>`, and caches each result by resolved URL for the session.
130
+ *
131
+ * Only video clips are probed — an over-scheduled audio clip merely goes silent,
132
+ * which is not the visible "frozen frame" bug this addresses.
133
+ */
134
+
135
+ /**
136
+ * Probe the intrinsic durations of the video clips in `schedule`. Returns a map
137
+ * keyed by the clip's raw `src`. Pass the resolved `MediaProvider` explicitly
138
+ * (editor hosts) or rely on {@link MediaContext} (player hosts) by omitting it.
139
+ */
140
+ declare function useMediaClipDurations(schedule: ScheduledClip[], basePath: string, mediaProviderOverride?: MediaProvider | null): Map<string, number>;
141
+
142
+ export { type DocPlayerAppearanceOverrides, type MountOptions, PipPosition, PipShape, PipSize, type ResolvedDocPlayerAppearance, type SquisqPlayerHandle, SquisqRenderAPI, VideoPresentation$1 as VideoPresentation, resolveDocPlayerAppearance, useMediaClipDurations };
package/dist/index.js CHANGED
@@ -9,8 +9,10 @@ import {
9
9
  DocProgressBar,
10
10
  MediaClipLayer,
11
11
  SocialCaptionOverlay,
12
- formatTime
13
- } from "./chunk-IUFWLNXS.js";
12
+ formatTime,
13
+ resolveDocPlayerAppearance,
14
+ useMediaClipDurations
15
+ } from "./chunk-EKD6JMJN.js";
14
16
  import {
15
17
  BlockRenderer,
16
18
  CanvasSection,
@@ -40,7 +42,7 @@ import {
40
42
  useDocPlayback,
41
43
  useMediaSchedule,
42
44
  useViewportOrientation
43
- } from "./chunk-NWZQGZIJ.js";
45
+ } from "./chunk-BOZJ655L.js";
44
46
  import {
45
47
  JsonView
46
48
  } from "./chunk-NANF7REM.js";
@@ -97,9 +99,11 @@ export {
97
99
  formatTime,
98
100
  getAnimationStyle,
99
101
  getTransitionClass,
102
+ resolveDocPlayerAppearance,
100
103
  useAudioSync,
101
104
  useAutoSurface,
102
105
  useDocPlayback,
106
+ useMediaClipDurations,
103
107
  useMediaProvider,
104
108
  useMediaSchedule,
105
109
  useMediaUrl,
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Block, Doc, Theme, SurfaceScheme, Transition, CaptionTrack, ViewportConfig as ViewportConfig$1, ScheduledClip } from '@bendyline/squisq/schemas';
2
+ import { Block, VideoPresentation as VideoPresentation$1, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, Theme, SurfaceScheme, Transition, CaptionTrack, ViewportConfig as ViewportConfig$1, ScheduledClip } from '@bendyline/squisq/schemas';
3
3
  import { ViewportConfig } from '@bendyline/squisq/doc';
4
4
  import { a as AudioController } from '../AudioController-DwMsPe38.js';
5
+ import { CSSProperties } from 'react';
5
6
 
6
7
  /**
7
8
  * Doc Player Control Types
@@ -20,6 +21,19 @@ import { a as AudioController } from '../AudioController-DwMsPe38.js';
20
21
 
21
22
  /** Layout mode for doc player controls */
22
23
  type ControlsLayout = 'overlay' | 'sidebar' | 'bottom';
24
+ /**
25
+ * Placement of scheduled video relative to the rendered slide.
26
+ *
27
+ * `'background'` preserves the legacy full-bleed treatment behind the
28
+ * content. The other variants render above the content for presenter video.
29
+ */
30
+ type VideoPresentation = VideoPresentation$1;
31
+ /** Size of a picture-in-picture presenter video. */
32
+ type PipSize = VideoPipSize;
33
+ /** Shape of a picture-in-picture presenter video. */
34
+ type PipShape = VideoPipShape;
35
+ /** Corner occupied by a picture-in-picture presenter video. */
36
+ type PipPosition = VideoPipPosition;
23
37
  /**
24
38
  * Display mode for DocPlayer.
25
39
  *
@@ -151,7 +165,10 @@ interface RenderChapterInfo {
151
165
  * ```
152
166
  */
153
167
  interface SquisqRenderAPI {
168
+ /** Seek and resolve only after the requested visual state is capture-ready. */
154
169
  seekTo: (time: number) => Promise<void>;
170
+ /** Timeline time most recently committed to the player DOM. */
171
+ getRenderedTime: () => number;
155
172
  getDuration: () => number;
156
173
  getBlocks: () => RenderBlockInfo[];
157
174
  getAudioSegments: () => RenderAudioSegmentInfo[];
@@ -178,6 +195,8 @@ interface DocPlayerProps {
178
195
  /** Receives the instance-scoped render API, and `null` on cleanup. */
179
196
  onRenderAPIReady?: (api: SquisqRenderAPI | null) => void;
180
197
  autoPlay?: boolean;
198
+ /** Restart Video-mode playback automatically when the timeline ends. */
199
+ loop?: boolean;
181
200
  onEnded?: () => void;
182
201
  onTimeUpdate?: (time: number) => void;
183
202
  /** Optional host-owned audio controller. */
@@ -205,6 +224,17 @@ interface DocPlayerProps {
205
224
  showCoverSlide?: boolean;
206
225
  coverVisible?: boolean;
207
226
  captionStyle?: CaptionStyle;
227
+ /**
228
+ * Placement of scheduled video relative to the slide content.
229
+ * Defaults to `'background'` for backward compatibility.
230
+ */
231
+ videoPresentation?: VideoPresentation;
232
+ /** Size of presenter video in picture-in-picture mode (default `'small'`). */
233
+ pipSize?: PipSize;
234
+ /** Shape of presenter video in picture-in-picture mode (default `'square'`). */
235
+ pipShape?: PipShape;
236
+ /** Corner used by presenter video in picture-in-picture mode. */
237
+ pipPosition?: PipPosition;
208
238
  enableSwipe?: boolean;
209
239
  globalKeyboardShortcuts?: boolean;
210
240
  }
@@ -327,6 +357,8 @@ interface DocPlayerWithSidebarProps {
327
357
  /** Base path for resolving media URLs (default: `'.'`) */
328
358
  basePath?: string;
329
359
  autoPlay?: boolean;
360
+ /** Restart playback automatically when the video timeline ends. */
361
+ loop?: boolean;
330
362
  onEnded?: () => void;
331
363
  onTimeUpdate?: (time: number) => void;
332
364
  /** Optional audio controller (if not provided, uses default HTML5 audio) */
@@ -349,7 +381,7 @@ interface DocPlayerWithSidebarProps {
349
381
  */
350
382
  theme?: Theme;
351
383
  }
352
- declare function DocPlayerWithSidebar({ doc, basePath, autoPlay, onEnded, onTimeUpdate, audioController, animationsEnabled, muted, captionsEnabled, isFullscreen, onFullscreenToggle, forceViewport, onPlayingChange, theme, }: DocPlayerWithSidebarProps): react_jsx_runtime.JSX.Element;
384
+ declare function DocPlayerWithSidebar({ doc, basePath, autoPlay, loop, onEnded, onTimeUpdate, audioController, animationsEnabled, muted, captionsEnabled, isFullscreen, onFullscreenToggle, forceViewport, onPlayingChange, theme, }: DocPlayerWithSidebarProps): react_jsx_runtime.JSX.Element;
353
385
 
354
386
  interface DocProgressBarProps {
355
387
  state: PlaybackState;
@@ -404,7 +436,21 @@ interface MediaClipLayerProps {
404
436
  renderMode?: boolean;
405
437
  /** Silence every scheduled clip during live playback. */
406
438
  muted?: boolean;
439
+ /** Placement of video clips relative to the rendered document. */
440
+ presentation?: VideoPresentation;
441
+ /** Size of picture-in-picture video (small or large). */
442
+ pipSize?: PipSize;
443
+ /** Shape of picture-in-picture video (square or 16:9 wide). */
444
+ pipShape?: PipShape;
445
+ /** Corner occupied by picture-in-picture video. */
446
+ pipPosition?: PipPosition;
447
+ /** Orientation of the rendered player viewport. */
448
+ pipOrientation?: 'landscape' | 'portrait';
449
+ /** Resolved theme frame applied directly to PIP video during raster capture. */
450
+ pipFrameStyle?: Pick<CSSProperties, 'border' | 'borderRadius' | 'boxShadow'>;
451
+ /** Honor each scheduled video's authored placement override. Default true. */
452
+ honorClipPresentation?: boolean;
407
453
  }
408
- declare function MediaClipLayer({ schedule, currentTime, isPlaying, basePath, renderMode, muted, }: MediaClipLayerProps): react_jsx_runtime.JSX.Element | null;
454
+ declare function MediaClipLayer({ schedule, currentTime, isPlaying, basePath, renderMode, muted, presentation, pipSize, pipShape, pipPosition, pipOrientation, pipFrameStyle, honorClipPresentation, }: MediaClipLayerProps): react_jsx_runtime.JSX.Element | null;
409
455
 
410
- export { type BlockMarker, BlockRenderer, type CaptionMode, CaptionOverlay, type CaptionStyle, type ControlsLayout, type DisplayMode, DocControlsBottom, DocControlsOverlay, DocControlsSidebar, DocControlsSlideshow, DocPlayer, type DocPlayerProps, DocPlayerWithSidebar, DocProgressBar, InlineAudioPlayer, type InlineAudioPlayerProps, InlineVideoPlayer, type InlineVideoPlayerProps, MediaClipLayer, type MediaClipLayerProps, type PlaybackActions, type PlaybackState, type RenderAudioSegmentInfo, type RenderBlockInfo, type RenderCaptionInfo, type RenderChapterInfo, type SlideNavActions, SocialCaptionOverlay, type SquisqRenderAPI, formatTime };
456
+ export { type BlockMarker, BlockRenderer, type CaptionMode, CaptionOverlay, type CaptionStyle, type ControlsLayout, type DisplayMode, DocControlsBottom, DocControlsOverlay, DocControlsSidebar, DocControlsSlideshow, DocPlayer, type DocPlayerProps, DocPlayerWithSidebar, DocProgressBar, InlineAudioPlayer, type InlineAudioPlayerProps, InlineVideoPlayer, type InlineVideoPlayerProps, MediaClipLayer, type MediaClipLayerProps, type PipPosition, type PipShape, type PipSize, type PlaybackActions, type PlaybackState, type RenderAudioSegmentInfo, type RenderBlockInfo, type RenderCaptionInfo, type RenderChapterInfo, type SlideNavActions, SocialCaptionOverlay, type SquisqRenderAPI, type VideoPresentation, formatTime };
@@ -10,12 +10,12 @@ import {
10
10
  MediaClipLayer,
11
11
  SocialCaptionOverlay,
12
12
  formatTime
13
- } from "../chunk-IUFWLNXS.js";
13
+ } from "../chunk-EKD6JMJN.js";
14
14
  import {
15
15
  BlockRenderer
16
16
  } from "../chunk-M2HEFJZP.js";
17
17
  import "../chunk-XYS7HMP4.js";
18
- import "../chunk-NWZQGZIJ.js";
18
+ import "../chunk-BOZJ655L.js";
19
19
  import "../chunk-TT6ENR6T.js";
20
20
  import {
21
21
  InlineAudioPlayer,