@bendyline/squisq-react 2.4.7 → 2.6.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.
@@ -9,14 +9,14 @@ import {
9
9
  TreeLayer,
10
10
  VideoLayer,
11
11
  getTransitionClass
12
- } from "./chunk-MKWVJYUS.js";
12
+ } from "./chunk-UJEHDVQO.js";
13
13
  import {
14
14
  useAutoSurface
15
15
  } from "./chunk-TT6ENR6T.js";
16
16
  import {
17
17
  InlineVideoPlayer,
18
18
  MarkdownRenderer
19
- } from "./chunk-VMPQEUJH.js";
19
+ } from "./chunk-TMCLQNLM.js";
20
20
  import {
21
21
  useMediaUrl
22
22
  } from "./chunk-LR3AIGDD.js";
@@ -165,7 +165,8 @@ var defaultValue = {
165
165
  viewport: VIEWPORT_PRESETS.landscape,
166
166
  renderContext: { theme: DEFAULT_THEME },
167
167
  animationsEnabled: true,
168
- imageDisplayMode: "inline"
168
+ imageDisplayMode: "inline",
169
+ showCodeCopyButton: false
169
170
  };
170
171
  var PageViewContext = createContext(defaultValue);
171
172
  function usePageView() {
@@ -438,11 +439,19 @@ function CardGridSection({ section }) {
438
439
  ] });
439
440
  }
440
441
  function ItemListSection({ section }) {
441
- const { theme } = usePageView();
442
+ const { theme, showCodeCopyButton, onCopyCode } = usePageView();
442
443
  const items = section.slots.items ?? [];
443
444
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
444
445
  section.slots.title && /* @__PURE__ */ jsx3("h2", { className: "squisq-page-section-title squisq-page-items-title", children: section.slots.title }),
445
- /* @__PURE__ */ jsx3("ol", { className: "squisq-page-items", children: items.map((item, i) => /* @__PURE__ */ jsx3("li", { children: item.markdown ? /* @__PURE__ */ jsx3(MarkdownRenderer, { nodes: item.markdown, theme }) : item.body }, i)) })
446
+ /* @__PURE__ */ jsx3("ol", { className: "squisq-page-items", children: items.map((item, i) => /* @__PURE__ */ jsx3("li", { children: item.markdown ? /* @__PURE__ */ jsx3(
447
+ MarkdownRenderer,
448
+ {
449
+ nodes: item.markdown,
450
+ theme,
451
+ showCodeCopyButton,
452
+ onCopyCode
453
+ }
454
+ ) : item.body }, i)) })
446
455
  ] });
447
456
  }
448
457
  function TimelineRailSection({ section }) {
@@ -470,12 +479,28 @@ function TableSection({ section }) {
470
479
  ] });
471
480
  }
472
481
  function ProseSection({ section, block }) {
473
- const { theme } = usePageView();
474
- const heading = section.slots.title !== void 0 && block?.sourceHeading ? /* @__PURE__ */ jsx3(MarkdownRenderer, { nodes: [block.sourceHeading], theme }) : null;
482
+ const { theme, showCodeCopyButton, onCopyCode } = usePageView();
483
+ const heading = section.slots.title !== void 0 && block?.sourceHeading ? /* @__PURE__ */ jsx3(
484
+ MarkdownRenderer,
485
+ {
486
+ nodes: [block.sourceHeading],
487
+ theme,
488
+ showCodeCopyButton,
489
+ onCopyCode
490
+ }
491
+ ) : null;
475
492
  const bodyNodes = section.slots.body?.markdown ?? block?.contents;
476
493
  return /* @__PURE__ */ jsxs2("div", { className: "squisq-page-prose", children: [
477
494
  heading,
478
- bodyNodes && bodyNodes.length > 0 && /* @__PURE__ */ jsx3(MarkdownRenderer, { nodes: bodyNodes, theme })
495
+ bodyNodes && bodyNodes.length > 0 && /* @__PURE__ */ jsx3(
496
+ MarkdownRenderer,
497
+ {
498
+ nodes: bodyNodes,
499
+ theme,
500
+ showCodeCopyButton,
501
+ onCopyCode
502
+ }
503
+ )
479
504
  ] });
480
505
  }
481
506
  function FooterSection({ section }) {
@@ -537,7 +562,7 @@ function sectionBody(entry, featureFlip) {
537
562
  }
538
563
  }
539
564
  function PageSectionView({ entry, featureFlip, isLeadProse }) {
540
- const { pageStyle, theme } = usePageView();
565
+ const { pageStyle, theme, showCodeCopyButton, onCopyCode } = usePageView();
541
566
  const { section } = entry;
542
567
  const richContent = section.slots.richContent?.markdown;
543
568
  const classes = [
@@ -566,7 +591,15 @@ function PageSectionView({ entry, featureFlip, isLeadProse }) {
566
591
  ...hintAttrs,
567
592
  children: /* @__PURE__ */ jsxs3("div", { className: "squisq-page-section-inner", children: [
568
593
  sectionBody(entry, featureFlip),
569
- richContent && richContent.length > 0 && /* @__PURE__ */ jsx4("div", { className: "squisq-page-rich-content", children: /* @__PURE__ */ jsx4(MarkdownRenderer, { nodes: richContent, theme }) })
594
+ richContent && richContent.length > 0 && /* @__PURE__ */ jsx4("div", { className: "squisq-page-rich-content", children: /* @__PURE__ */ jsx4(
595
+ MarkdownRenderer,
596
+ {
597
+ nodes: richContent,
598
+ theme,
599
+ showCodeCopyButton,
600
+ onCopyCode
601
+ }
602
+ ) })
570
603
  ] })
571
604
  }
572
605
  );
@@ -603,7 +636,9 @@ function LinearDocView({
603
636
  imageDisplayMode = "inline",
604
637
  globalKeyboardShortcuts = false,
605
638
  showCover = true,
606
- transformPage
639
+ transformPage,
640
+ showCodeCopyButton = false,
641
+ onCopyCode
607
642
  }) {
608
643
  const scrollRef = useRef(null);
609
644
  const activeViewport = viewport ?? VIEWPORT_PRESETS2.landscape;
@@ -650,7 +685,9 @@ function LinearDocView({
650
685
  viewport: activeViewport,
651
686
  renderContext,
652
687
  animationsEnabled,
653
- imageDisplayMode
688
+ imageDisplayMode,
689
+ showCodeCopyButton,
690
+ onCopyCode
654
691
  }),
655
692
  [
656
693
  activeTheme,
@@ -659,7 +696,9 @@ function LinearDocView({
659
696
  activeViewport,
660
697
  renderContext,
661
698
  animationsEnabled,
662
- imageDisplayMode
699
+ imageDisplayMode,
700
+ showCodeCopyButton,
701
+ onCopyCode
663
702
  ]
664
703
  );
665
704
  const { featureOrdinals, leadProseIndex } = useMemo2(() => {
@@ -239,7 +239,7 @@ function remapToKenBurns(anim) {
239
239
  }
240
240
 
241
241
  // src/layers/TextLayer.tsx
242
- import { useId, useMemo } from "react";
242
+ import { useId, useLayoutEffect, useMemo, useRef, useState } from "react";
243
243
  import { DEFAULT_DOC_FONT } from "@bendyline/squisq/schemas";
244
244
  import {
245
245
  parseHtmlToNodes,
@@ -454,6 +454,55 @@ function PlainTextLayer({ layer, viewport, blockTime }) {
454
454
  }
455
455
  const lineHeight = style.lineHeight || 1.4;
456
456
  const lineHeightPx = style.fontSize * lineHeight;
457
+ const shrinkToFit = style.shrinkToFit === true;
458
+ const centerBlock = shrinkToFit && dominantBaseline === "middle";
459
+ const firstLineDy = centerBlock ? -((lines.length - 1) / 2) * lineHeightPx : 0;
460
+ const textRef = useRef(null);
461
+ const [fit, setFit] = useState(null);
462
+ const linesKey = lines.join("\n");
463
+ useLayoutEffect(() => {
464
+ if (!shrinkToFit) {
465
+ setFit(null);
466
+ return;
467
+ }
468
+ const element = textRef.current;
469
+ if (!element || typeof element.getBBox !== "function") return;
470
+ const measure = () => {
471
+ try {
472
+ const bbox = element.getBBox();
473
+ if (bbox.width <= 0 || bbox.height <= 0) return;
474
+ const maxW = boxWidth ?? viewport.width;
475
+ const maxH = boxHeight ?? viewport.height;
476
+ const scale = Math.min(1, maxW / bbox.width, maxH / bbox.height);
477
+ setFit(
478
+ scale < 0.995 ? { scale, cx: bbox.x + bbox.width / 2, cy: bbox.y + bbox.height / 2 } : null
479
+ );
480
+ } catch {
481
+ }
482
+ };
483
+ measure();
484
+ const fonts = element.ownerDocument?.fonts;
485
+ if (fonts && fonts.status !== "loaded") {
486
+ let cancelled = false;
487
+ void fonts.ready.then(() => {
488
+ if (!cancelled) measure();
489
+ });
490
+ return () => {
491
+ cancelled = true;
492
+ };
493
+ }
494
+ }, [
495
+ shrinkToFit,
496
+ linesKey,
497
+ boxWidth,
498
+ boxHeight,
499
+ viewport.width,
500
+ viewport.height,
501
+ style.fontSize,
502
+ style.fontFamily,
503
+ style.fontWeight
504
+ ]);
505
+ const fitTransform = fit ? `translate(${fit.cx} ${fit.cy}) scale(${fit.scale}) translate(${-fit.cx} ${-fit.cy})` : void 0;
457
506
  const textStyles = {
458
507
  fontSize: `${style.fontSize}px`,
459
508
  fontFamily: style.fontFamily || DEFAULT_DOC_FONT,
@@ -486,13 +535,15 @@ function PlainTextLayer({ layer, viewport, blockTime }) {
486
535
  /* @__PURE__ */ jsx3(
487
536
  "text",
488
537
  {
538
+ ref: textRef,
489
539
  x,
490
540
  y,
491
541
  textAnchor,
492
542
  dominantBaseline,
493
543
  style: textStyles,
494
544
  filter: filterId ? `url(#${filterId})` : void 0,
495
- children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tspan", { x, dy: i === 0 ? 0 : lineHeightPx, children: [
545
+ transform: fitTransform,
546
+ children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tspan", { x, dy: i === 0 ? firstLineDy : lineHeightPx, children: [
496
547
  line || "\xA0",
497
548
  " "
498
549
  ] }, i))
@@ -893,7 +944,7 @@ function MarkerDef({
893
944
  }
894
945
 
895
946
  // src/layers/MapLayer.tsx
896
- import { useId as useId4, useState, useEffect } from "react";
947
+ import { useId as useId4, useState as useState2, useEffect } from "react";
897
948
  import { ResourcePolicyError as ResourcePolicyError2 } from "@bendyline/squisq/markdown";
898
949
 
899
950
  // src/utils/mapTileUtils.ts
@@ -1092,10 +1143,10 @@ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1092
1143
  function MapLayer({ layer, basePath, viewport, blockTime }) {
1093
1144
  const { content, position, animation } = layer;
1094
1145
  const clipId = `map-clip-${useId4().replace(/:/g, "")}-${layer.id}`;
1095
- const [mapImageUrl, setMapImageUrl] = useState(null);
1096
- const [isLoading, setIsLoading] = useState(true);
1097
- const [error, setError] = useState(null);
1098
- const [blockedByPolicy, setBlockedByPolicy] = useState(false);
1146
+ const [mapImageUrl, setMapImageUrl] = useState2(null);
1147
+ const [isLoading, setIsLoading] = useState2(true);
1148
+ const [error, setError] = useState2(null);
1149
+ const [blockedByPolicy, setBlockedByPolicy] = useState2(false);
1099
1150
  const x = resolveValue(position.x, viewport.width);
1100
1151
  const y = resolveValue(position.y, viewport.height);
1101
1152
  const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;
@@ -1242,7 +1293,7 @@ function MapLayer({ layer, basePath, viewport, blockTime }) {
1242
1293
  }
1243
1294
 
1244
1295
  // src/layers/VideoLayer.tsx
1245
- import { useRef, useEffect as useEffect2 } from "react";
1296
+ import { useRef as useRef2, useEffect as useEffect2 } from "react";
1246
1297
  import { jsx as jsx7 } from "react/jsx-runtime";
1247
1298
  var VIDEO_SYNC_DRIFT_SECONDS = 0.2;
1248
1299
  function VideoLayer({
@@ -1254,8 +1305,8 @@ function VideoLayer({
1254
1305
  muted = false
1255
1306
  }) {
1256
1307
  const { content, position } = layer;
1257
- const videoRef = useRef(null);
1258
- const hasStartedRef = useRef(false);
1308
+ const videoRef = useRef2(null);
1309
+ const hasStartedRef = useRef2(false);
1259
1310
  const startAt = content.startAt ?? 0;
1260
1311
  const gated = blockTime < startAt;
1261
1312
  const x = resolveValue(position.x, viewport.width);
@@ -1434,7 +1485,7 @@ function TableLayer({ layer, viewport, blockTime }) {
1434
1485
  }
1435
1486
 
1436
1487
  // src/layers/TreeLayer.tsx
1437
- import { useState as useState2 } from "react";
1488
+ import { useState as useState3 } from "react";
1438
1489
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1439
1490
  function faClass(token, fallback) {
1440
1491
  const name = token && token.trim() ? token.trim() : fallback;
@@ -1508,7 +1559,7 @@ function TreeRow({
1508
1559
  style
1509
1560
  }) {
1510
1561
  const hasChildren = item.children.length > 0;
1511
- const [collapsed, setCollapsed] = useState2(false);
1562
+ const [collapsed, setCollapsed] = useState3(false);
1512
1563
  const isDir = item.isDir || hasChildren;
1513
1564
  const iconCls = isDir ? faClass(style.folderIcon, collapsed ? "folder" : "folder-open") : faClass(style.fileIcon, "file");
1514
1565
  return /* @__PURE__ */ jsxs7("li", { style: { position: "relative" }, children: [
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-TT6ENR6T.js";
4
4
  import {
5
5
  MarkdownRenderer
6
- } from "./chunk-VMPQEUJH.js";
6
+ } from "./chunk-TMCLQNLM.js";
7
7
 
8
8
  // src/jsonView/useJsonViewTokens.ts
9
9
  import { useMemo } from "react";
@@ -18,10 +18,14 @@ import { ResourcePolicy } from '@bendyline/squisq/markdown';
18
18
  * This is the HTML5 Audio implementation of the AudioController interface.
19
19
  * Hosts that drive audio through an external player (e.g. a native shell)
20
20
  * can supply their own AudioController to DocPlayer instead of this hook.
21
+ *
22
+ * In `synthetic` mode there is no audio element to follow, so a caller that
23
+ * has no segments passes `syntheticDuration` — the document's own timeline
24
+ * length — and the same segment machinery drives a timer instead.
21
25
  */
22
26
 
23
27
  type AudioSyncMode = 'media' | 'synthetic';
24
- declare function useAudioSync(audioRef: RefObject<HTMLAudioElement>, audioTrack: AudioTrack | undefined, basePath?: string, enabled?: boolean, mode?: AudioSyncMode): AudioController;
28
+ declare function useAudioSync(audioRef: RefObject<HTMLAudioElement>, track: AudioTrack | undefined, basePath?: string, enabled?: boolean, mode?: AudioSyncMode, syntheticDuration?: number): AudioController;
25
29
 
26
30
  interface ModalDialogOptions {
27
31
  /** The backdrop/portal root. Siblings of this branch are made inert. */
@@ -6,7 +6,7 @@ import {
6
6
  useDocPlayback,
7
7
  useMediaSchedule,
8
8
  useViewportOrientation
9
- } from "../chunk-BOZJ655L.js";
9
+ } from "../chunk-MVJQL2W2.js";
10
10
  import {
11
11
  useAutoSurface
12
12
  } from "../chunk-TT6ENR6T.js";
package/dist/index.d.ts CHANGED
@@ -1,12 +1,15 @@
1
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
3
  import { Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, ScheduledClip, MediaProvider } from '@bendyline/squisq/schemas';
4
- export { MarkdownRenderer, MermaidDiagram, MermaidDiagramProps } from './markdown/index.js';
4
+ import { C as CodeBlockCopyHandler } from './MarkdownRenderer-CerBKw-c.js';
5
+ export { a as CodeBlockCopyContext, M as MarkdownRenderer, b as MarkdownRendererProps } from './MarkdownRenderer-CerBKw-c.js';
6
+ export { MermaidDiagram, MermaidDiagramProps } from './markdown/index.js';
5
7
  export { CanvasSection, CanvasSectionProps, ImageDisplayMode, LinearDocView, LinearDocViewProps, PageSectionView, PageSectionViewProps, PageViewContext, PageViewContextValue, usePageView } from './page/index.js';
6
8
  export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TableLayer, TextLayer, TreeLayer, VideoLayer } from './layers/index.js';
9
+ import { CoverSlideTemplate, CoverSlidePlayback } from '@bendyline/squisq/doc';
10
+ export { getAnimationStyle, getTransitionClass } from '@bendyline/squisq/doc';
7
11
  export { MediaContext, MediaScheduleController, ModalDialogOptions, ResourcePolicyContext, UseDocPlaybackOptions, useAudioSync, useAutoSurface, useDocPlayback, useMediaProvider, useMediaSchedule, useMediaUrl, useModalDialog, useResourcePolicy, useViewportOrientation } from './hooks/index.js';
8
12
  export { A as AudioActions, a as AudioController, b as AudioState } from './AudioController-DwMsPe38.js';
9
- export { getAnimationStyle, getTransitionClass } from '@bendyline/squisq/doc';
10
13
  export { JsonView, JsonViewProps } from './json-view/index.js';
11
14
  import 'react/jsx-runtime';
12
15
  import 'react';
@@ -83,6 +86,10 @@ interface MountOptions {
83
86
  animationsEnabled?: boolean;
84
87
  /** Caption style: 'standard' or 'social'. Omit or set to undefined for no captions. */
85
88
  captionStyle?: 'standard' | 'social';
89
+ /** Show a Copy button on fenced code blocks in static mode (default: false). */
90
+ showCodeCopyButton?: boolean;
91
+ /** Optional host clipboard adapter; otherwise the browser Clipboard API is used. */
92
+ onCopyCode?: CodeBlockCopyHandler;
86
93
  }
87
94
  /** Instance handle returned by {@link mount}. */
88
95
  interface SquisqPlayerHandle {
@@ -103,6 +110,9 @@ interface DocPlayerAppearanceOverrides {
103
110
  pipShape?: PipShape;
104
111
  pipPosition?: PipPosition;
105
112
  showCoverSlide?: boolean;
113
+ coverSlideTemplate?: CoverSlideTemplate;
114
+ coverSlideDuration?: number;
115
+ coverSlidePlayback?: CoverSlidePlayback;
106
116
  }
107
117
  interface ResolvedDocPlayerAppearance {
108
118
  theme: Theme;
@@ -111,6 +121,9 @@ interface ResolvedDocPlayerAppearance {
111
121
  pipShape: PipShape;
112
122
  pipPosition: PipPosition;
113
123
  showCoverSlide: boolean;
124
+ coverSlideTemplate: CoverSlideTemplate;
125
+ coverSlideDuration: number;
126
+ coverSlidePlayback: CoverSlidePlayback;
114
127
  }
115
128
  /** Resolve the visual settings a standalone/export player must inherit from its Doc. */
116
129
  declare function resolveDocPlayerAppearance(doc: Doc, overrides?: DocPlayerAppearanceOverrides): ResolvedDocPlayerAppearance;
@@ -140,4 +153,4 @@ declare function resolveDocPlayerAppearance(doc: Doc, overrides?: DocPlayerAppea
140
153
  */
141
154
  declare function useMediaClipDurations(schedule: ScheduledClip[], basePath: string, mediaProviderOverride?: MediaProvider | null): Map<string, number>;
142
155
 
143
- export { type DocPlayerAppearanceOverrides, type MountOptions, PipPosition, PipShape, PipSize, type ResolvedDocPlayerAppearance, type SquisqPlayerHandle, SquisqRenderAPI, VideoPresentation$1 as VideoPresentation, resolveDocPlayerAppearance, useMediaClipDurations };
156
+ export { CodeBlockCopyHandler, type DocPlayerAppearanceOverrides, type MountOptions, PipPosition, PipShape, PipSize, type ResolvedDocPlayerAppearance, type SquisqPlayerHandle, SquisqRenderAPI, VideoPresentation$1 as VideoPresentation, resolveDocPlayerAppearance, useMediaClipDurations };
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  formatTime,
13
13
  resolveDocPlayerAppearance,
14
14
  useMediaClipDurations
15
- } from "./chunk-KF4DTT46.js";
15
+ } from "./chunk-GWD62KLD.js";
16
16
  import {
17
17
  BlockRenderer,
18
18
  CanvasSection,
@@ -20,7 +20,7 @@ import {
20
20
  PageSectionView,
21
21
  PageViewContext,
22
22
  usePageView
23
- } from "./chunk-3HYSWEKG.js";
23
+ } from "./chunk-U6P7HBUY.js";
24
24
  import {
25
25
  ImageLayer,
26
26
  MapLayer,
@@ -33,7 +33,7 @@ import {
33
33
  VideoLayer,
34
34
  getAnimationStyle,
35
35
  getTransitionClass
36
- } from "./chunk-MKWVJYUS.js";
36
+ } from "./chunk-UJEHDVQO.js";
37
37
  import {
38
38
  useModalDialog
39
39
  } from "./chunk-65POMKHR.js";
@@ -42,10 +42,10 @@ import {
42
42
  useDocPlayback,
43
43
  useMediaSchedule,
44
44
  useViewportOrientation
45
- } from "./chunk-BOZJ655L.js";
45
+ } from "./chunk-MVJQL2W2.js";
46
46
  import {
47
47
  JsonView
48
- } from "./chunk-DJRYQQXB.js";
48
+ } from "./chunk-YKBVTYU4.js";
49
49
  import {
50
50
  useAutoSurface
51
51
  } from "./chunk-TT6ENR6T.js";
@@ -53,7 +53,7 @@ import {
53
53
  InlineAudioPlayer,
54
54
  InlineVideoPlayer,
55
55
  MarkdownRenderer
56
- } from "./chunk-VMPQEUJH.js";
56
+ } from "./chunk-TMCLQNLM.js";
57
57
  import {
58
58
  MermaidDiagram
59
59
  } from "./chunk-WLUZTUNZ.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  JsonView
3
- } from "../chunk-DJRYQQXB.js";
3
+ } from "../chunk-YKBVTYU4.js";
4
4
  import "../chunk-TT6ENR6T.js";
5
- import "../chunk-VMPQEUJH.js";
5
+ import "../chunk-TMCLQNLM.js";
6
6
  import "../chunk-WLUZTUNZ.js";
7
7
  import "../chunk-LR3AIGDD.js";
8
8
  export {
@@ -8,7 +8,7 @@ import {
8
8
  TextLayer,
9
9
  TreeLayer,
10
10
  VideoLayer
11
- } from "../chunk-MKWVJYUS.js";
11
+ } from "../chunk-UJEHDVQO.js";
12
12
  import "../chunk-WLUZTUNZ.js";
13
13
  import "../chunk-LR3AIGDD.js";
14
14
  export {
@@ -1,35 +1,7 @@
1
+ export { a as CodeBlockCopyContext, C as CodeBlockCopyHandler, M as MarkdownRenderer, b as MarkdownRendererProps } from '../MarkdownRenderer-CerBKw-c.js';
1
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
3
  import { Theme } from '@bendyline/squisq/schemas';
3
- import { MarkdownBlockNode, HtmlPolicy } from '@bendyline/squisq/markdown';
4
-
5
- interface MarkdownRendererProps {
6
- /** Block-level AST nodes to render */
7
- nodes: MarkdownBlockNode[];
8
- /** Optional CSS class for the wrapper element */
9
- className?: string;
10
- /**
11
- * Raw HTML policy. Defaults to `sanitize`, which removes unsafe tags,
12
- * event handlers, and executable URL schemes before rendering.
13
- */
14
- htmlPolicy?: HtmlPolicy;
15
- /**
16
- * Extra URL schemes to allow on links (e.g. a host app's internal
17
- * navigation scheme it intercepts on click). Executable schemes are
18
- * never allowed regardless. See {@link SanitizeUrlOptions}.
19
- */
20
- linkSchemes?: readonly string[];
21
- /** Resolved Squisq theme inherited by embedded Mermaid diagrams. */
22
- theme?: Theme;
23
- }
24
- /**
25
- * Renders MarkdownBlockNode[] AST as React HTML elements.
26
- *
27
- * @example
28
- * ```tsx
29
- * <MarkdownRenderer nodes={block.contents} />
30
- * ```
31
- */
32
- declare function MarkdownRenderer({ nodes, className, htmlPolicy, linkSchemes, theme, }: MarkdownRendererProps): react_jsx_runtime.JSX.Element | null;
4
+ import '@bendyline/squisq/markdown';
33
5
 
34
6
  interface MermaidDiagramProps {
35
7
  source: string;
@@ -41,4 +13,4 @@ interface MermaidDiagramProps {
41
13
  /** Read-only Mermaid rendering for page bodies and slide layers. */
42
14
  declare function MermaidDiagram({ source, className, ariaLabel, theme, }: MermaidDiagramProps): react_jsx_runtime.JSX.Element;
43
15
 
44
- export { MarkdownRenderer, MermaidDiagram, type MermaidDiagramProps };
16
+ export { MermaidDiagram, type MermaidDiagramProps };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MarkdownRenderer
3
- } from "../chunk-VMPQEUJH.js";
3
+ } from "../chunk-TMCLQNLM.js";
4
4
  import {
5
5
  MermaidDiagram
6
6
  } from "../chunk-WLUZTUNZ.js";
@@ -1,7 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { Doc, ViewportConfig, Theme, SurfaceScheme, ThemePageStyle } from '@bendyline/squisq/schemas';
3
3
  import { PageTransformHints, PageSectionMaterialization, PageSection, MaterializeBlockLayersOptions } from '@bendyline/squisq/doc';
4
+ import { C as CodeBlockCopyHandler } from '../MarkdownRenderer-CerBKw-c.js';
5
+ export { a as CodeBlockCopyContext } from '../MarkdownRenderer-CerBKw-c.js';
4
6
  import * as react from 'react';
7
+ import '@bendyline/squisq/markdown';
5
8
 
6
9
  interface LinearDocViewProps {
7
10
  /**
@@ -63,6 +66,10 @@ interface LinearDocViewProps {
63
66
  * emphasis-curve adjustments defined by `TransformStyleConfig.page`.
64
67
  */
65
68
  transformPage?: PageTransformHints;
69
+ /** Show a Copy button on ordinary fenced code blocks (default: false). */
70
+ showCodeCopyButton?: boolean;
71
+ /** Optional host clipboard adapter; otherwise the browser Clipboard API is used. */
72
+ onCopyCode?: CodeBlockCopyHandler;
66
73
  }
67
74
  type ImageDisplayMode = 'inline' | 'thumbnail';
68
75
  /**
@@ -73,7 +80,7 @@ type ImageDisplayMode = 'inline' | 'thumbnail';
73
80
  * <LinearDocView doc={doc} basePath="/media/" />
74
81
  * ```
75
82
  */
76
- declare function LinearDocView({ doc, markdown, basePath, viewport, className, theme, surface, animationsEnabled, thinMargins, imageDisplayMode, globalKeyboardShortcuts, showCover, transformPage, }: LinearDocViewProps): react_jsx_runtime.JSX.Element;
83
+ declare function LinearDocView({ doc, markdown, basePath, viewport, className, theme, surface, animationsEnabled, thinMargins, imageDisplayMode, globalKeyboardShortcuts, showCover, transformPage, showCodeCopyButton, onCopyCode, }: LinearDocViewProps): react_jsx_runtime.JSX.Element;
77
84
 
78
85
  interface PageSectionViewProps {
79
86
  entry: PageSectionMaterialization;
@@ -98,8 +105,10 @@ interface PageViewContextValue {
98
105
  renderContext: MaterializeBlockLayersOptions;
99
106
  animationsEnabled: boolean;
100
107
  imageDisplayMode: ImageDisplayMode;
108
+ showCodeCopyButton: boolean;
109
+ onCopyCode?: CodeBlockCopyHandler;
101
110
  }
102
111
  declare const PageViewContext: react.Context<PageViewContextValue>;
103
112
  declare function usePageView(): PageViewContextValue;
104
113
 
105
- export { CanvasSection, type CanvasSectionProps, type ImageDisplayMode, LinearDocView, type LinearDocViewProps, PageSectionView, type PageSectionViewProps, PageViewContext, type PageViewContextValue, usePageView };
114
+ export { CanvasSection, type CanvasSectionProps, CodeBlockCopyHandler, type ImageDisplayMode, LinearDocView, type LinearDocViewProps, PageSectionView, type PageSectionViewProps, PageViewContext, type PageViewContextValue, usePageView };
@@ -4,10 +4,10 @@ import {
4
4
  PageSectionView,
5
5
  PageViewContext,
6
6
  usePageView
7
- } from "../chunk-3HYSWEKG.js";
8
- import "../chunk-MKWVJYUS.js";
7
+ } from "../chunk-U6P7HBUY.js";
8
+ import "../chunk-UJEHDVQO.js";
9
9
  import "../chunk-TT6ENR6T.js";
10
- import "../chunk-VMPQEUJH.js";
10
+ import "../chunk-TMCLQNLM.js";
11
11
  import "../chunk-WLUZTUNZ.js";
12
12
  import "../chunk-LR3AIGDD.js";
13
13
  export {
@@ -1,8 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
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
- import { ViewportConfig } from '@bendyline/squisq/doc';
3
+ import { ViewportConfig, CoverSlideTemplate, CoverSlidePlayback } from '@bendyline/squisq/doc';
4
4
  import { a as AudioController } from '../AudioController-DwMsPe38.js';
5
+ import { C as CodeBlockCopyHandler } from '../MarkdownRenderer-CerBKw-c.js';
6
+ export { a as CodeBlockCopyContext } from '../MarkdownRenderer-CerBKw-c.js';
5
7
  import { CSSProperties } from 'react';
8
+ import '@bendyline/squisq/markdown';
6
9
 
7
10
  /**
8
11
  * Doc Player Control Types
@@ -222,6 +225,12 @@ interface DocPlayerProps {
222
225
  /** Video, manual slideshow, or long-scrolling linear rendition. */
223
226
  displayMode?: DisplayMode;
224
227
  showCoverSlide?: boolean;
228
+ /** Visual template used to materialize the managed cover. */
229
+ coverSlideTemplate?: CoverSlideTemplate;
230
+ /** Seconds the cover remains visible after Video playback starts. */
231
+ coverSlideDuration?: number;
232
+ /** Whether video export advances or delays the story while the cover is visible. */
233
+ coverSlidePlayback?: CoverSlidePlayback;
225
234
  coverVisible?: boolean;
226
235
  captionStyle?: CaptionStyle;
227
236
  /**
@@ -237,6 +246,10 @@ interface DocPlayerProps {
237
246
  pipPosition?: PipPosition;
238
247
  enableSwipe?: boolean;
239
248
  globalKeyboardShortcuts?: boolean;
249
+ /** Show a Copy button on fenced code blocks in linear mode (default: false). */
250
+ showCodeCopyButton?: boolean;
251
+ /** Optional host clipboard adapter; otherwise the browser Clipboard API is used. */
252
+ onCopyCode?: CodeBlockCopyHandler;
240
253
  }
241
254
 
242
255
  /**
@@ -455,4 +468,4 @@ interface MediaClipLayerProps {
455
468
  }
456
469
  declare function MediaClipLayer({ schedule, currentTime, isPlaying, basePath, renderMode, muted, presentation, pipSize, pipShape, pipPosition, pipOrientation, pipFrameStyle, honorClipPresentation, }: MediaClipLayerProps): react_jsx_runtime.JSX.Element | null;
457
470
 
458
- 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 };
471
+ export { type BlockMarker, BlockRenderer, type CaptionMode, CaptionOverlay, type CaptionStyle, CodeBlockCopyHandler, 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,17 +10,17 @@ import {
10
10
  MediaClipLayer,
11
11
  SocialCaptionOverlay,
12
12
  formatTime
13
- } from "../chunk-KF4DTT46.js";
13
+ } from "../chunk-GWD62KLD.js";
14
14
  import {
15
15
  BlockRenderer
16
- } from "../chunk-3HYSWEKG.js";
17
- import "../chunk-MKWVJYUS.js";
18
- import "../chunk-BOZJ655L.js";
16
+ } from "../chunk-U6P7HBUY.js";
17
+ import "../chunk-UJEHDVQO.js";
18
+ import "../chunk-MVJQL2W2.js";
19
19
  import "../chunk-TT6ENR6T.js";
20
20
  import {
21
21
  InlineAudioPlayer,
22
22
  InlineVideoPlayer
23
- } from "../chunk-VMPQEUJH.js";
23
+ } from "../chunk-TMCLQNLM.js";
24
24
  import "../chunk-WLUZTUNZ.js";
25
25
  import "../chunk-LR3AIGDD.js";
26
26
  export {