@bendyline/squisq-react 2.2.0 → 2.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.
package/dist/index.d.ts CHANGED
@@ -1,272 +1,17 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Block, Doc, Theme, SurfaceScheme, Transition, CaptionTrack, ViewportConfig as ViewportConfig$1, ThemePageStyle, ImageLayer as ImageLayer$1, TextLayer as TextLayer$1, ShapeLayer as ShapeLayer$1, PathLayer as PathLayer$1, VideoLayer as VideoLayer$1, TableLayer as TableLayer$1, TreeLayer as TreeLayer$1, MapLayer as MapLayer$1, MermaidLayer as MermaidLayer$1, ScheduledClip, AudioTrack, MediaProvider } from '@bendyline/squisq/schemas';
3
- import { ViewportConfig, PageTransformHints, PageSectionMaterialization, PageSection, MaterializeBlockLayersOptions, ViewportOrientation } from '@bendyline/squisq/doc';
1
+ import { SquisqRenderAPI } from './player/index.js';
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';
4
+ export { MarkdownRenderer, MermaidDiagram, MermaidDiagramProps } from './markdown/index.js';
5
+ export { CanvasSection, CanvasSectionProps, ImageDisplayMode, LinearDocView, LinearDocViewProps, PageSectionView, PageSectionViewProps, PageViewContext, PageViewContextValue, usePageView } from './page/index.js';
6
+ export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TableLayer, TextLayer, TreeLayer, VideoLayer } from './layers/index.js';
7
+ export { MediaContext, MediaScheduleController, ModalDialogOptions, ResourcePolicyContext, UseDocPlaybackOptions, useAudioSync, useAutoSurface, useDocPlayback, useMediaProvider, useMediaSchedule, useMediaUrl, useModalDialog, useResourcePolicy, useViewportOrientation } from './hooks/index.js';
8
+ export { A as AudioActions, a as AudioController, b as AudioState } from './AudioController-DwMsPe38.js';
4
9
  export { getAnimationStyle, getTransitionClass } from '@bendyline/squisq/doc';
5
- import { MarkdownBlockNode, HtmlPolicy, ResourcePolicy } from '@bendyline/squisq/markdown';
6
- import * as react from 'react';
7
- import { RefObject } from 'react';
8
- import { SquisqAnnotatedSchema } from '@bendyline/squisq/jsonForm';
9
-
10
- /**
11
- * AudioController - Abstraction for audio playback in DocPlayer
12
- *
13
- * This module defines an interface for audio playback operations that can have
14
- * different implementations depending on the runtime environment:
15
- *
16
- * - Site/Browser: Uses HTML5 Audio element directly
17
- * - EFB/MSFS: Routes through CompanionAPI to Electron app
18
- *
19
- * The DocPlayer uses this abstraction instead of directly manipulating audio,
20
- * allowing the same component code to work in both environments.
21
- */
22
-
23
- interface AudioState {
24
- /** Current time in overall timeline (seconds) */
25
- currentTime: number;
26
- /** Whether audio is currently playing */
27
- isPlaying: boolean;
28
- /** Index of current audio segment */
29
- currentSegment: number;
30
- /** Total duration of all segments */
31
- totalDuration: number;
32
- /** Whether audio has finished */
33
- isEnded: boolean;
34
- /** Whether audio is loaded and ready to play */
35
- isReady: boolean;
36
- /** Whether the audio backend is available/connected */
37
- isAvailable: boolean;
38
- /** Message to show when not available */
39
- unavailableMessage?: string;
40
- }
41
- interface AudioActions {
42
- /** Start or resume playback */
43
- play: () => Promise<void>;
44
- /** Pause playback */
45
- pause: () => Promise<void>;
46
- /** Toggle play/pause */
47
- toggle: () => Promise<void>;
48
- /** Seek to specific time in timeline */
49
- seekTo: (time: number) => Promise<void>;
50
- /** Skip to specific segment */
51
- skipToSegment: (index: number) => Promise<void>;
52
- /** Restart from beginning */
53
- restart: () => Promise<void>;
54
- }
55
- type AudioController = AudioState & AudioActions;
56
-
57
- /**
58
- * Doc Player Control Types
59
- *
60
- * Shared type definitions for doc player controls across different
61
- * layout modes (overlay, sidebar, bottom). These interfaces allow
62
- * control components to be decoupled from the core DocPlayer.
63
- *
64
- * Related Files:
65
- * - DocPlayer.tsx — Core player component
66
- * - DocProgressBar.tsx — Extracted progress bar
67
- * - DocControlsOverlay.tsx — Overlay controls (default)
68
- * - DocControlsSidebar.tsx — Vertical sidebar controls
69
- * - DocControlsBottom.tsx — Horizontal bottom strip controls
70
- */
71
-
72
- /** Layout mode for doc player controls */
73
- type ControlsLayout = 'overlay' | 'sidebar' | 'bottom';
74
- /**
75
- * Display mode for DocPlayer.
76
- *
77
- * - `'video'` — Traditional video-style playback with play/pause, scrub bar,
78
- * and time-based auto-advance. Default mode.
79
- * - `'slideshow'` — PowerPoint-style presentation with prev/next navigation.
80
- * Blocks are treated as static slides that only change on user click.
81
- * No auto-advance, no scrub bar.
82
- * - `'linear'` — Long-scrolling document view. Renders the full markdown as
83
- * readable HTML with template-annotated sections shown as inline SVG cards.
84
- * No audio, no timeline, no controls — just a scrollable page.
85
- * - `'page'` — Plain semantic HTML preview matching what the
86
- * `markdownDocToPlainHtml` export produces. No SquisqPlayer, no SVG
87
- * cards — just `<h1>`/`<p>`/`<ul>` etc. inside a sandboxed iframe.
88
- * Use when you want a WYSIWYG view of the simple HTML export.
89
- * - `'narrate'` — Teleprompter/performance surface. DocPlayer does not
90
- * implement this mode; it is owned by the editor package
91
- * (`@bendyline/squisq-editor-react`), which renders its own
92
- * voice-paced teleprompter view for it.
93
- */
94
- type DisplayMode = 'video' | 'slideshow' | 'linear' | 'page' | 'narrate';
95
- /**
96
- * Caption display style.
97
- *
98
- * - `'standard'` — Traditional broadcast-style captions: small white text
99
- * on a semi-transparent black badge at the top of the player.
100
- * - `'social'` — Social media-style (Instagram/TikTok): large centered words
101
- * showing 3-5 words at a time with the active word highlighted in the
102
- * theme's primary color. Font and colors pulled from the active theme.
103
- */
104
- type CaptionStyle = 'standard' | 'social';
105
- /**
106
- * Caption display mode — combines enable/disable with style selection.
107
- * The CC button cycles through: off → standard → social → off.
108
- */
109
- type CaptionMode = 'off' | 'standard' | 'social';
110
- /** Slide navigation actions for slideshow display mode */
111
- interface SlideNavActions {
112
- /** Navigate to the next slide */
113
- nextSlide: () => void;
114
- /** Navigate to the previous slide */
115
- prevSlide: () => void;
116
- /** Navigate to a specific slide by index (0-based) */
117
- goToSlide: (index: number) => void;
118
- }
119
- /** Playback state exposed to external control components */
120
- interface PlaybackState$1 {
121
- isPlaying: boolean;
122
- currentTime: number;
123
- totalDuration: number;
124
- /** Whether the managed cover is the visual currently shown. */
125
- isCoverVisible?: boolean;
126
- currentBlockIndex: number;
127
- totalBlocks: number;
128
- docProgress: number;
129
- hasCaptions: boolean;
130
- captionsEnabled: boolean;
131
- /** Current caption display mode (off, standard, social). */
132
- captionMode: CaptionMode;
133
- isFullscreen?: boolean;
134
- /** Current audio segment index (0-based) */
135
- currentSegmentIndex: number;
136
- /** Current audio segment name (e.g., 'intro', 'history') */
137
- currentSegmentName: string | null;
138
- /** Current block data (for extracting image info, etc.) */
139
- currentBlock: Block | null;
140
- /** Optional display label for non-block slides, e.g. the managed cover. */
141
- currentSlideLabel?: string;
142
- /** Optional human-facing slide number, separate from internal nav index. */
143
- currentSlideNumber?: number;
144
- /** Optional human-facing slide total, separate from internal nav total. */
145
- totalSlideNumber?: number;
146
- }
147
- /** Playback actions exposed to external control components */
148
- interface PlaybackActions$1 {
149
- toggle: () => void;
150
- restart: () => void;
151
- seekTo: (time: number) => void;
152
- setCaptionsEnabled: (enabled: boolean) => void;
153
- /** Cycle caption mode: off → standard → social → off */
154
- cycleCaptionMode: () => void;
155
- toggleFullscreen?: () => void;
156
- }
157
- /** Block marker data for the progress bar */
158
- interface BlockMarker {
159
- block: Block;
160
- index: number;
161
- position: number;
162
- title: string;
163
- /** True if this block is the first in a new audio segment (section boundary) */
164
- isSectionStart: boolean;
165
- }
166
- /** Block metadata returned by SquisqRenderAPI.getBlocks() */
167
- interface RenderBlockInfo {
168
- id: string;
169
- template: string;
170
- startTime: number;
171
- duration: number;
172
- }
173
- /** Audio segment info returned by SquisqRenderAPI.getAudioSegments() */
174
- interface RenderAudioSegmentInfo {
175
- src: string;
176
- name: string;
177
- duration: number;
178
- startTime: number;
179
- }
180
- /** Caption phrase info returned by SquisqRenderAPI.getCaptions() */
181
- interface RenderCaptionInfo {
182
- text: string;
183
- startTime: number;
184
- endTime: number;
185
- }
186
- /** Chapter marker returned by SquisqRenderAPI.getChapters() */
187
- interface RenderChapterInfo {
188
- title: string;
189
- startTime: number;
190
- duration: number;
191
- }
192
- /**
193
- * Instance-scoped API created in render mode and debug mode.
194
- * React hosts receive it via `DocPlayer.onRenderAPIReady`; standalone hosts
195
- * receive it from their mount handle.
196
- *
197
- * @example
198
- * ```ts
199
- * const handle = SquisqPlayer.getHandle(rootElement);
200
- * const api = await handle?.renderAPI;
201
- * await api?.seekTo(5.0);
202
- * ```
203
- */
204
- interface SquisqRenderAPI {
205
- seekTo: (time: number) => Promise<void>;
206
- getDuration: () => number;
207
- getBlocks: () => RenderBlockInfo[];
208
- getAudioSegments: () => RenderAudioSegmentInfo[];
209
- getCaptions: () => RenderCaptionInfo[];
210
- getChapters: () => RenderChapterInfo[];
211
- showCover: () => Promise<void>;
212
- hideCover: () => Promise<void>;
213
- hasCoverBlock: () => boolean;
214
- }
215
- /** Format time in seconds to MM:SS string */
216
- declare function formatTime(seconds: number): string;
217
-
218
- interface DocPlayerProps {
219
- /** The Doc to play. Wins over `markdown` when both are provided. */
220
- doc?: Doc;
221
- /** Markdown source to convert when `doc` is absent. */
222
- markdown?: string;
223
- /** Base path for resolving media URLs (default: `'.'`). */
224
- basePath?: string;
225
- /** Render mode for deterministic video capture. */
226
- renderMode?: boolean;
227
- /** Render slide transitions and per-layer animations (default: true). */
228
- animationsEnabled?: boolean;
229
- /** Receives the instance-scoped render API, and `null` on cleanup. */
230
- onRenderAPIReady?: (api: SquisqRenderAPI | null) => void;
231
- autoPlay?: boolean;
232
- onEnded?: () => void;
233
- onTimeUpdate?: (time: number) => void;
234
- /** Optional host-owned audio controller. */
235
- audioController?: AudioController;
236
- /** Explicit synthetic clock for timed documents that intentionally have no audio asset. */
237
- audioMode?: 'media' | 'synthetic';
238
- showControls?: boolean;
239
- showScrubber?: boolean;
240
- muted?: boolean;
241
- captionsEnabled?: boolean;
242
- onCaptionsToggle?: (enabled: boolean) => void;
243
- onPlaybackStateChange?: (state: PlaybackState$1) => void;
244
- onControlsReady?: (controls: PlaybackActions$1 & {
245
- play: () => void;
246
- pause: () => void;
247
- }) => void;
248
- isFullscreen?: boolean;
249
- onFullscreenToggle?: () => void;
250
- onBlockMarkers?: (markers: BlockMarker[]) => void;
251
- forceViewport?: ViewportConfig;
252
- theme?: Theme;
253
- surface?: SurfaceScheme | 'auto';
254
- /** Video, manual slideshow, or long-scrolling linear rendition. */
255
- displayMode?: DisplayMode;
256
- showCoverSlide?: boolean;
257
- coverVisible?: boolean;
258
- captionStyle?: CaptionStyle;
259
- enableSwipe?: boolean;
260
- globalKeyboardShortcuts?: boolean;
261
- }
262
-
263
- /**
264
- * Front-door component: resolves the `doc` / `markdown` props into a Doc
265
- * and renders a themed empty state when neither is provided. The playback
266
- * machinery lives in `DocPlayerContent` so its hook order never changes
267
- * when a doc appears or disappears.
268
- */
269
- declare function DocPlayer(props: DocPlayerProps): react_jsx_runtime.JSX.Element;
10
+ export { JsonView, JsonViewProps } from './json-view/index.js';
11
+ import 'react/jsx-runtime';
12
+ import '@bendyline/squisq/markdown';
13
+ import 'react';
14
+ import '@bendyline/squisq/jsonForm';
270
15
 
271
16
  /**
272
17
  * Standalone Entry Point — IIFE bundle for self-contained HTML rendering.
@@ -342,639 +87,4 @@ interface SquisqPlayerHandle {
342
87
  unmount(): void;
343
88
  }
344
89
 
345
- /** Viewport configuration type */
346
- interface ViewportDimensions {
347
- width: number;
348
- height: number;
349
- }
350
- interface BlockRendererProps {
351
- /** The block to render */
352
- block: Block;
353
- /** Current time relative to block start (seconds) */
354
- blockTime: number;
355
- /** Base path for resolving media URLs */
356
- basePath: string;
357
- /** Whether this block is entering (for transition) */
358
- isEntering?: boolean;
359
- /** Whether this block is exiting (for transition) */
360
- isExiting?: boolean;
361
- /** Transition to apply. Defaults to block.transition. */
362
- transition?: Transition;
363
- /** Viewport dimensions (defaults to 1920x1080 landscape) */
364
- viewport?: ViewportDimensions;
365
- /** Whether the doc is currently playing (controls video playback) */
366
- isPlaying?: boolean;
367
- /**
368
- * Whether to render block transitions and layer animations (default: true).
369
- * Disabling this only removes authored/render-style motion; timed video
370
- * layers continue to advance normally.
371
- */
372
- animationsEnabled?: boolean;
373
- }
374
- declare function BlockRenderer({ block, blockTime, basePath, isEntering, isExiting, transition, viewport, isPlaying, animationsEnabled, }: BlockRendererProps): react_jsx_runtime.JSX.Element;
375
-
376
- interface CaptionOverlayProps {
377
- /** Caption track with timestamped phrases */
378
- captions: CaptionTrack | undefined;
379
- /** Current playback time in seconds */
380
- currentTime: number;
381
- /** Whether captions are enabled */
382
- enabled?: boolean;
383
- /** Font size in pixels for standard style (default: 16) */
384
- fontSize?: number;
385
- /** Caption display style (default: 'standard') */
386
- captionStyle?: CaptionStyle;
387
- /** Theme for social-style caption colors and fonts */
388
- theme?: Theme;
389
- /** Viewport config for social-style font scaling */
390
- viewport?: ViewportConfig$1;
391
- }
392
- declare function CaptionOverlay({ captions, currentTime, enabled, fontSize, captionStyle, theme, viewport, }: CaptionOverlayProps): react_jsx_runtime.JSX.Element;
393
-
394
- interface SocialCaptionOverlayProps {
395
- captions: CaptionTrack | undefined;
396
- currentTime: number;
397
- enabled?: boolean;
398
- theme?: Theme;
399
- viewport?: ViewportConfig$1;
400
- }
401
- declare function SocialCaptionOverlay({ captions, currentTime, enabled, theme, viewport, }: SocialCaptionOverlayProps): react_jsx_runtime.JSX.Element | null;
402
-
403
- interface DocControlsOverlayProps {
404
- state: PlaybackState$1;
405
- actions: PlaybackActions$1;
406
- blockMarkers: BlockMarker[];
407
- expandedBlocks: Block[];
408
- getBlockTitle?: (block: Block) => string;
409
- }
410
- declare function DocControlsOverlay({ state, actions, blockMarkers, expandedBlocks, getBlockTitle, }: DocControlsOverlayProps): react_jsx_runtime.JSX.Element;
411
-
412
- interface DocControlsBottomProps {
413
- state: PlaybackState$1;
414
- actions: PlaybackActions$1;
415
- blockMarkers: BlockMarker[];
416
- expandedBlocks: Block[];
417
- getBlockTitle?: (block: Block) => string;
418
- }
419
- declare function DocControlsBottom({ state, actions, blockMarkers, expandedBlocks, getBlockTitle, }: DocControlsBottomProps): react_jsx_runtime.JSX.Element;
420
-
421
- interface DocControlsSidebarProps {
422
- state: PlaybackState$1;
423
- actions: PlaybackActions$1;
424
- }
425
- declare function DocControlsSidebar({ state, actions }: DocControlsSidebarProps): react_jsx_runtime.JSX.Element;
426
-
427
- interface SlideshowPickerItem {
428
- /** Stable identifier for the slide/block. */
429
- id: string;
430
- /** Human-facing slide number, or a special label such as "Cover". */
431
- label: string;
432
- /** Short description shown in the slide picker. */
433
- summary: string;
434
- }
435
- interface DocControlsSlideshowProps {
436
- state: PlaybackState$1;
437
- slideNav: SlideNavActions;
438
- /** Slides available for direct navigation from the counter popover. */
439
- slides?: readonly SlideshowPickerItem[];
440
- /** Controlled open state for hosts that expose their own picker shortcut. */
441
- pickerOpen?: boolean;
442
- /** Called whenever the slide picker should open or close. */
443
- onPickerOpenChange?: (open: boolean) => void;
444
- }
445
- declare function DocControlsSlideshow({ state, slideNav, slides, pickerOpen, onPickerOpenChange, }: DocControlsSlideshowProps): react_jsx_runtime.JSX.Element;
446
-
447
- interface DocPlayerWithSidebarProps {
448
- /** The Doc to play */
449
- doc: Doc;
450
- /** Base path for resolving media URLs (default: `'.'`) */
451
- basePath?: string;
452
- autoPlay?: boolean;
453
- onEnded?: () => void;
454
- onTimeUpdate?: (time: number) => void;
455
- /** Optional audio controller (if not provided, uses default HTML5 audio) */
456
- audioController?: AudioController;
457
- /** Whether to render slide transitions and per-layer animations (default: true). */
458
- animationsEnabled?: boolean;
459
- muted?: boolean;
460
- captionsEnabled?: boolean;
461
- isFullscreen?: boolean;
462
- onFullscreenToggle?: () => void;
463
- /** Force a specific viewport preset, bypassing window-based orientation detection. */
464
- forceViewport?: ViewportConfig$1;
465
- /** Called when playing state changes */
466
- onPlayingChange?: (isPlaying: boolean) => void;
467
- /**
468
- * Theme for rendering. Forwarded to the inner DocPlayer so the sidebar
469
- * (portrait) layout matches the default (landscape) layout — without it the
470
- * inner player falls back to DEFAULT_THEME, whose dark text is unreadable
471
- * over a hero cover image.
472
- */
473
- theme?: Theme;
474
- }
475
- declare function DocPlayerWithSidebar({ doc, basePath, autoPlay, onEnded, onTimeUpdate, audioController, animationsEnabled, muted, captionsEnabled, isFullscreen, onFullscreenToggle, forceViewport, onPlayingChange, theme, }: DocPlayerWithSidebarProps): react_jsx_runtime.JSX.Element;
476
-
477
- interface DocProgressBarProps {
478
- state: PlaybackState$1;
479
- actions: PlaybackActions$1;
480
- blockMarkers: BlockMarker[];
481
- /** All expanded blocks for hover lookup */
482
- expandedBlocks: Block[];
483
- /** Optional: get block title for hover tooltip */
484
- getBlockTitle?: (block: Block) => string;
485
- }
486
- declare function DocProgressBar({ state, actions, blockMarkers, expandedBlocks, getBlockTitle, }: DocProgressBarProps): react_jsx_runtime.JSX.Element;
487
-
488
- interface MarkdownRendererProps {
489
- /** Block-level AST nodes to render */
490
- nodes: MarkdownBlockNode[];
491
- /** Optional CSS class for the wrapper element */
492
- className?: string;
493
- /**
494
- * Raw HTML policy. Defaults to `sanitize`, which removes unsafe tags,
495
- * event handlers, and executable URL schemes before rendering.
496
- */
497
- htmlPolicy?: HtmlPolicy;
498
- /**
499
- * Extra URL schemes to allow on links (e.g. a host app's internal
500
- * navigation scheme it intercepts on click). Executable schemes are
501
- * never allowed regardless. See {@link SanitizeUrlOptions}.
502
- */
503
- linkSchemes?: readonly string[];
504
- }
505
- /**
506
- * Renders MarkdownBlockNode[] AST as React HTML elements.
507
- *
508
- * @example
509
- * ```tsx
510
- * <MarkdownRenderer nodes={block.contents} />
511
- * ```
512
- */
513
- declare function MarkdownRenderer({ nodes, className, htmlPolicy, linkSchemes, }: MarkdownRendererProps): react_jsx_runtime.JSX.Element | null;
514
-
515
- interface MermaidDiagramProps {
516
- source: string;
517
- className?: string;
518
- ariaLabel?: string;
519
- }
520
- /** Read-only Mermaid rendering for page bodies and slide layers. */
521
- declare function MermaidDiagram({ source, className, ariaLabel, }: MermaidDiagramProps): react_jsx_runtime.JSX.Element;
522
-
523
- interface LinearDocViewProps {
524
- /**
525
- * The Doc to render. Wins over `markdown` when both are provided.
526
- * When neither `doc` nor `markdown` is given, an empty container renders.
527
- */
528
- doc?: Doc;
529
- /**
530
- * Markdown source to render. When `doc` is absent, the markdown is parsed
531
- * and converted to a Doc via `markdownToDoc(parseMarkdown(markdown))`.
532
- * Ignored when `doc` is provided.
533
- */
534
- markdown?: string;
535
- /** Base path for resolving media URLs (images, etc.) */
536
- basePath?: string;
537
- /** Viewport config for embedded SVG canvas sections (default: landscape) */
538
- viewport?: ViewportConfig$1;
539
- /** Optional CSS class for the outer container */
540
- className?: string;
541
- /** Theme to use for rendering (default: DEFAULT_THEME from the theme library) */
542
- theme?: Theme;
543
- /** Whether embedded canvas sections render their layer animations (default: true). */
544
- animationsEnabled?: boolean;
545
- /**
546
- * Optional surface scheme (light / dark paper) overlaid on top of the
547
- * theme's colors. Orthogonal to `theme` — a theme picks editorial
548
- * identity, a surface picks the paper. Pass `'auto'` to follow the
549
- * user's OS `prefers-color-scheme`, a `SurfaceScheme` object to force a
550
- * specific surface, or omit to use the theme's built-in colors.
551
- */
552
- surface?: SurfaceScheme | 'auto';
553
- /**
554
- * Use tight padding + a hugging layout. The default layout is a full
555
- * page with themed section bands. Short conversational snippets like
556
- * chat replies benefit from a much tighter layout. Set to `true` to
557
- * render with minimal padding so the content hugs its container.
558
- */
559
- thinMargins?: boolean;
560
- /**
561
- * How images inside the doc should be sized. `'inline'` (default)
562
- * flows them at natural size up to the column width; `'thumbnail'`
563
- * constrains each image to a 100×100 box with aspect-preserving
564
- * containment — use for chat history and other dense surfaces where
565
- * full-size images would dominate the layout.
566
- */
567
- imageDisplayMode?: ImageDisplayMode;
568
- /**
569
- * Let unmodified Up/Down arrows scroll this view even when it does not
570
- * currently hold focus. Intended for a primary document preview.
571
- */
572
- globalKeyboardShortcuts?: boolean;
573
- /**
574
- * Synthesize a hero section from `doc.startBlock` at the top of the
575
- * page (default: true). The editor's Cover toggle maps here.
576
- */
577
- showCover?: boolean;
578
- /**
579
- * Page hints from the active transform (Summarize) style — spacing and
580
- * emphasis-curve adjustments defined by `TransformStyleConfig.page`.
581
- */
582
- transformPage?: PageTransformHints;
583
- }
584
- type ImageDisplayMode = 'inline' | 'thumbnail';
585
- /**
586
- * Renders a Doc as a scrolling, theme-art-directed page.
587
- *
588
- * @example
589
- * ```tsx
590
- * <LinearDocView doc={doc} basePath="/media/" />
591
- * ```
592
- */
593
- declare function LinearDocView({ doc, markdown, basePath, viewport, className, theme, surface, animationsEnabled, thinMargins, imageDisplayMode, globalKeyboardShortcuts, showCover, transformPage, }: LinearDocViewProps): react_jsx_runtime.JSX.Element;
594
-
595
- interface PageSectionViewProps {
596
- entry: PageSectionMaterialization;
597
- /** Alternation flip for feature-split sections (theme `alternate` hint). */
598
- featureFlip?: boolean;
599
- /** True when this is the doc's lead prose section (drop-cap target). */
600
- isLeadProse?: boolean;
601
- }
602
- declare function PageSectionView({ entry, featureFlip, isLeadProse }: PageSectionViewProps): react_jsx_runtime.JSX.Element;
603
-
604
- interface CanvasSectionProps {
605
- section: PageSection;
606
- }
607
- declare function CanvasSection({ section }: CanvasSectionProps): react_jsx_runtime.JSX.Element | null;
608
-
609
- interface PageViewContextValue {
610
- theme: Theme;
611
- pageStyle: ThemePageStyle;
612
- basePath: string;
613
- viewport: ViewportConfig$1;
614
- /** Options for `materializeBlockLayers` inside canvas embeds. */
615
- renderContext: MaterializeBlockLayersOptions;
616
- animationsEnabled: boolean;
617
- imageDisplayMode: ImageDisplayMode;
618
- }
619
- declare const PageViewContext: react.Context<PageViewContextValue>;
620
- declare function usePageView(): PageViewContextValue;
621
-
622
- interface InlineVideoPlayerProps {
623
- /** Source path — resolved through MediaContext when relative. */
624
- src: string;
625
- /** Base path used when no MediaProvider is in context. */
626
- basePath?: string;
627
- /** Optional explicit width (pixels or CSS length). */
628
- width?: number | string;
629
- /** Optional explicit height (pixels or CSS length). */
630
- height?: number | string;
631
- /** Optional poster image src — also resolved through MediaContext. */
632
- poster?: string;
633
- /** Whether to show native controls. Defaults to true. */
634
- controls?: boolean;
635
- /** `preload` attribute passthrough. Defaults to `'metadata'`. */
636
- preload?: 'none' | 'metadata' | 'auto';
637
- /** Extra className on the wrapper. */
638
- className?: string;
639
- }
640
- declare function InlineVideoPlayer({ src, basePath, width, height, poster, controls, preload, className, }: InlineVideoPlayerProps): react_jsx_runtime.JSX.Element | null;
641
-
642
- interface InlineAudioPlayerProps {
643
- /** Source path — resolved through MediaContext when relative. */
644
- src: string;
645
- /** Base path used when no MediaProvider is in context. */
646
- basePath?: string;
647
- /** Whether to show native controls. Defaults to true. */
648
- controls?: boolean;
649
- /** `preload` attribute passthrough. Defaults to `'metadata'`. */
650
- preload?: 'none' | 'metadata' | 'auto';
651
- /** Extra className on the wrapper. */
652
- className?: string;
653
- }
654
- declare function InlineAudioPlayer({ src, basePath, controls, preload, className, }: InlineAudioPlayerProps): react_jsx_runtime.JSX.Element | null;
655
-
656
- interface ImageLayerProps {
657
- layer: ImageLayer$1;
658
- /** Base path for resolving relative image URLs */
659
- basePath: string;
660
- /** Viewport dimensions for percentage calculations */
661
- viewport: {
662
- width: number;
663
- height: number;
664
- };
665
- /** Current time relative to block start (for animation timing) */
666
- blockTime: number;
667
- /** Whether authored and responsive image motion should run. */
668
- animationsEnabled?: boolean;
669
- }
670
- declare function ImageLayer({ layer, basePath, viewport, blockTime, animationsEnabled, }: ImageLayerProps): react_jsx_runtime.JSX.Element;
671
-
672
- interface TextLayerProps {
673
- layer: TextLayer$1;
674
- /** Viewport dimensions for percentage calculations */
675
- viewport: {
676
- width: number;
677
- height: number;
678
- };
679
- /** Current time relative to block start */
680
- blockTime: number;
681
- }
682
- /**
683
- * Dispatch between the plain SVG-text renderer and the rich HTML renderer
684
- * based on whether the layer carries `content.html`.
685
- */
686
- declare function TextLayer(props: TextLayerProps): react_jsx_runtime.JSX.Element;
687
-
688
- interface ShapeLayerProps {
689
- layer: ShapeLayer$1;
690
- /** Viewport dimensions for percentage calculations */
691
- viewport: {
692
- width: number;
693
- height: number;
694
- };
695
- /** Current time relative to block start */
696
- blockTime: number;
697
- }
698
- declare function ShapeLayer({ layer, viewport, blockTime }: ShapeLayerProps): react_jsx_runtime.JSX.Element;
699
-
700
- interface PathLayerProps {
701
- layer: PathLayer$1;
702
- /** Viewport dimensions — used to resolve `%` positions for named shapes. */
703
- viewport: {
704
- width: number;
705
- height: number;
706
- };
707
- /** Current time relative to block start. */
708
- blockTime: number;
709
- }
710
- declare function PathLayer({ layer, viewport, blockTime }: PathLayerProps): react_jsx_runtime.JSX.Element;
711
-
712
- interface VideoLayerProps {
713
- layer: VideoLayer$1;
714
- /** Base path for resolving relative video URLs */
715
- basePath: string;
716
- /** Viewport dimensions for percentage calculations */
717
- viewport: {
718
- width: number;
719
- height: number;
720
- };
721
- /** Current time relative to block start (for playback sync) */
722
- blockTime: number;
723
- /** Whether the doc is currently playing */
724
- isPlaying?: boolean;
725
- }
726
- declare function VideoLayer({ layer, basePath, viewport, blockTime, isPlaying }: VideoLayerProps): react_jsx_runtime.JSX.Element;
727
-
728
- interface TableLayerProps {
729
- layer: TableLayer$1;
730
- /** Viewport dimensions for percentage calculations */
731
- viewport: {
732
- width: number;
733
- height: number;
734
- };
735
- /** Current time relative to block start (for animation) */
736
- blockTime: number;
737
- }
738
- declare function TableLayer({ layer, viewport, blockTime }: TableLayerProps): react_jsx_runtime.JSX.Element;
739
-
740
- interface TreeLayerProps {
741
- layer: TreeLayer$1;
742
- viewport: {
743
- width: number;
744
- height: number;
745
- };
746
- blockTime: number;
747
- }
748
- declare function TreeLayer({ layer, viewport, blockTime }: TreeLayerProps): react_jsx_runtime.JSX.Element;
749
-
750
- interface MapLayerProps {
751
- layer: MapLayer$1;
752
- /** Base path for resolving relative image URLs */
753
- basePath: string;
754
- /** Viewport dimensions for percentage calculations */
755
- viewport: {
756
- width: number;
757
- height: number;
758
- };
759
- /** Current time relative to block start (for animation timing) */
760
- blockTime: number;
761
- }
762
- declare function MapLayer({ layer, basePath, viewport, blockTime }: MapLayerProps): react_jsx_runtime.JSX.Element;
763
-
764
- interface MermaidLayerProps {
765
- layer: MermaidLayer$1;
766
- viewport: {
767
- width: number;
768
- height: number;
769
- };
770
- blockTime: number;
771
- }
772
- /** Mermaid diagram hosted in HTML inside the slide SVG. */
773
- declare function MermaidLayer({ layer, viewport, blockTime }: MermaidLayerProps): react_jsx_runtime.JSX.Element;
774
-
775
- interface MediaClipLayerProps {
776
- schedule: ScheduledClip[];
777
- currentTime: number;
778
- isPlaying: boolean;
779
- basePath: string;
780
- renderMode?: boolean;
781
- /** Silence every scheduled clip during live playback. */
782
- muted?: boolean;
783
- }
784
- declare function MediaClipLayer({ schedule, currentTime, isPlaying, basePath, renderMode, muted, }: MediaClipLayerProps): react_jsx_runtime.JSX.Element | null;
785
-
786
- /**
787
- * useAudioSync Hook
788
- *
789
- * Synchronizes playback state with an audio element. Provides current
790
- * playback time, playing state, and methods to control audio playback.
791
- *
792
- * Handles multiple audio segments (MP3 files) by tracking which segment
793
- * is currently playing and calculating the overall timeline position.
794
- *
795
- * This is the HTML5 Audio implementation of the AudioController interface.
796
- * Hosts that drive audio through an external player (e.g. a native shell)
797
- * can supply their own AudioController to DocPlayer instead of this hook.
798
- */
799
-
800
- type AudioSyncMode = 'media' | 'synthetic';
801
- declare function useAudioSync(audioRef: RefObject<HTMLAudioElement>, audioTrack: AudioTrack | undefined, basePath?: string, enabled?: boolean, mode?: AudioSyncMode): AudioController;
802
-
803
- interface ModalDialogOptions {
804
- /** The backdrop/portal root. Siblings of this branch are made inert. */
805
- rootRef: RefObject<HTMLElement | null>;
806
- /** The element with `role="dialog"`; focus is trapped within it. */
807
- dialogRef: RefObject<HTMLElement | null>;
808
- initialFocusRef?: RefObject<HTMLElement | null>;
809
- /** Explicit opener/owner to restore after unmount (important when a child uses autofocus). */
810
- returnFocusRef?: RefObject<HTMLElement | null>;
811
- onClose: () => void;
812
- }
813
- /** Shared focus, keyboard, background-isolation, and restoration behavior for modal dialogs. */
814
- declare function useModalDialog({ rootRef, dialogRef, initialFocusRef, returnFocusRef, onClose, }: ModalDialogOptions): void;
815
-
816
- /**
817
- * useMediaSchedule
818
- *
819
- * Pure follower of the playback clock for the media-clip model. Given the
820
- * resolved {@link ScheduledClip}s and the current time, it returns the clips
821
- * the player should mount and which of them are active right now.
822
- * {@link MediaClipLayer} consumes this to drive one hidden `<audio>` /
823
- * full-bleed `<video>` element per clip. (Annotation-authored clips all render
824
- * at the player level; template-produced `VideoLayer`s are a separate path and
825
- * are not part of the schedule.)
826
- *
827
- * It owns no clock: `currentTime`/`isPlaying` come from the existing
828
- * `useAudioSync` provider via `DocPlayer`. With an empty schedule it returns
829
- * empty lists, so documents without the new media model are unaffected.
830
- */
831
-
832
- interface MediaScheduleController {
833
- /** Clips the player mounts (every scheduled clip). */
834
- renderClips: ScheduledClip[];
835
- /** Ids of clips whose [absoluteStart, absoluteEnd) contains currentTime. */
836
- activeIds: Set<string>;
837
- }
838
- declare function useMediaSchedule(schedule: ScheduledClip[], currentTime: number): MediaScheduleController;
839
-
840
- /**
841
- * useDocPlayback Hook
842
- *
843
- * Manages the playback state for a visual doc, including which block
844
- * is currently active, transition states, and synchronization with audio.
845
- *
846
- * This hook provides:
847
- * - Current block determination based on time
848
- * - Transition tracking (entering/exiting blocks)
849
- * - Manual navigation (next/prev block)
850
- * - Time-based seeking
851
- * - Automatic expansion of template blocks
852
- */
853
-
854
- interface PlaybackState {
855
- /** Currently visible block */
856
- currentBlock: Block | null;
857
- /** Index of current block */
858
- currentBlockIndex: number;
859
- /** Previous block (for transitions) */
860
- previousBlock: Block | null;
861
- /** Whether current block is entering */
862
- isEntering: boolean;
863
- /** Whether previous block is exiting */
864
- isExiting: boolean;
865
- /** Time relative to current block start */
866
- blockTime: number;
867
- /** Progress through current block (0-1) */
868
- blockProgress: number;
869
- /** Overall progress through doc (0-1) */
870
- docProgress: number;
871
- /** Expanded blocks (templates converted to full blocks with layers) */
872
- blocks: Block[];
873
- }
874
- interface PlaybackActions {
875
- /** Go to next block */
876
- nextBlock: () => void;
877
- /** Go to previous block */
878
- prevBlock: () => void;
879
- /** Go to specific block by index */
880
- goToBlock: (index: number) => void;
881
- /**
882
- * Let the identified block enter without remounting the outgoing block.
883
- * Used when another interaction (such as a swipe) already removed it.
884
- */
885
- suppressOutgoingForNextBlock: (blockId: string) => void;
886
- }
887
- interface UseDocPlaybackOptions {
888
- /** Target viewport used to materialize template blocks. */
889
- viewport?: ViewportConfig;
890
- /** Active theme used for materialization and transition defaults. */
891
- theme?: Theme;
892
- /** Host seek callback used by block navigation actions. */
893
- onSeek?: (time: number) => void;
894
- }
895
- declare function useDocPlayback(script: Doc | null, currentTime: number, options?: UseDocPlaybackOptions): PlaybackState & PlaybackActions;
896
-
897
- /**
898
- * useViewportOrientation Hook
899
- *
900
- * Detects the current viewport orientation and returns the appropriate
901
- * VIEWPORT_PRESET for rendering docs. Automatically updates when
902
- * the window is resized.
903
- *
904
- * Thresholds:
905
- * - Portrait: height > width * 1.2 (significantly taller than wide)
906
- * - Square: width and height within 20% of each other
907
- * - Landscape: width > height * 1.2 (significantly wider than tall)
908
- */
909
-
910
- interface UseViewportOrientationResult {
911
- /** Current viewport preset configuration */
912
- viewport: ViewportConfig;
913
- /** Current orientation name */
914
- orientation: ViewportOrientation;
915
- /** Current window dimensions */
916
- windowSize: {
917
- width: number;
918
- height: number;
919
- };
920
- }
921
- /**
922
- * Hook to detect viewport orientation and return appropriate preset.
923
- * Updates automatically when window is resized.
924
- */
925
- declare function useViewportOrientation(): UseViewportOrientationResult;
926
-
927
- /**
928
- * React context holding the current MediaProvider (or null if none provided).
929
- */
930
- declare const MediaContext: react.Context<MediaProvider | null>;
931
- /**
932
- * Policy for document-controlled media URLs. Hosts rendering untrusted
933
- * documents can provide `LOCAL_ONLY_RESOURCE_POLICY` or an explicit host
934
- * allow-list without changing their MediaProvider.
935
- */
936
- declare const ResourcePolicyContext: react.Context<ResourcePolicy>;
937
- declare function useResourcePolicy(): ResourcePolicy;
938
- /**
939
- * Hook to access the current MediaProvider from context.
940
- * Returns null if no provider is set.
941
- */
942
- declare function useMediaProvider(): MediaProvider | null;
943
- /**
944
- * Hook to resolve a media URL via the MediaProvider (if available),
945
- * falling back to basePath-based resolution.
946
- *
947
- * Returns the resolved URL string. Updates when the provider or path changes.
948
- *
949
- * @param relativePath - Relative media path from the document (e.g., 'hero.jpg')
950
- * @param basePath - Fallback base path for URL construction
951
- */
952
- declare function useMediaUrl(relativePath: string, basePath: string): string;
953
-
954
- /**
955
- * Live-track `prefers-color-scheme` and return a stable SurfaceScheme.
956
- * `enabled: false` short-circuits to LIGHT_SURFACE (callers pass `false`
957
- * when a static surface was provided so the hook never observes the
958
- * media query). The `MediaQueryList` and the `subscribe`/`getSnapshot`
959
- * callbacks are memoized so `useSyncExternalStore` doesn't resubscribe on
960
- * every parent render.
961
- */
962
- declare function useAutoSurface(enabled: boolean): SurfaceScheme;
963
-
964
- interface JsonViewProps {
965
- /** Schema describing the value's shape (with optional `squisq` UI hints). */
966
- schema: SquisqAnnotatedSchema;
967
- /** The value to display. */
968
- value: unknown;
969
- /** Optional theme. Defaults to `DEFAULT_THEME`. */
970
- theme?: Theme;
971
- /** Light/dark surface override; `'auto'` follows `prefers-color-scheme`. */
972
- surface?: SurfaceScheme | 'auto';
973
- /** Padding/gap density. Default: 'comfortable'. */
974
- density?: 'comfortable' | 'compact';
975
- /** Optional CSS class for the outer container. */
976
- className?: string;
977
- }
978
- declare function JsonView(props: JsonViewProps): react_jsx_runtime.JSX.Element;
979
-
980
- export { type AudioActions, type AudioController, type AudioState, type BlockMarker, BlockRenderer, CanvasSection, type CanvasSectionProps, type CaptionMode, CaptionOverlay, type CaptionStyle, type ControlsLayout, type DisplayMode, DocControlsBottom, DocControlsOverlay, DocControlsSidebar, DocControlsSlideshow, DocPlayer, type DocPlayerProps, DocPlayerWithSidebar, DocProgressBar, type ImageDisplayMode, ImageLayer, InlineAudioPlayer, type InlineAudioPlayerProps, InlineVideoPlayer, type InlineVideoPlayerProps, JsonView, type JsonViewProps, LinearDocView, type LinearDocViewProps, MapLayer, MarkdownRenderer, MediaClipLayer, type MediaClipLayerProps, MediaContext, type MediaScheduleController, MermaidDiagram, type MermaidDiagramProps, MermaidLayer, type ModalDialogOptions, type MountOptions, PageSectionView, type PageSectionViewProps, PageViewContext, type PageViewContextValue, PathLayer, type PlaybackActions$1 as PlaybackActions, type PlaybackState$1 as PlaybackState, type RenderAudioSegmentInfo, type RenderBlockInfo, type RenderCaptionInfo, type RenderChapterInfo, ResourcePolicyContext, ShapeLayer, type SlideNavActions, SocialCaptionOverlay, type SquisqPlayerHandle, type SquisqRenderAPI, TableLayer, TextLayer, TreeLayer, type UseDocPlaybackOptions, VideoLayer, formatTime, useAudioSync, useAutoSurface, useDocPlayback, useMediaProvider, useMediaSchedule, useMediaUrl, useModalDialog, usePageView, useResourcePolicy, useViewportOrientation };
90
+ export { type MountOptions, type SquisqPlayerHandle, SquisqRenderAPI };