@bendyline/squisq-react 2.4.1 → 2.4.3

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BlockRenderer,
3
3
  LinearDocView
4
- } from "./chunk-M2HEFJZP.js";
4
+ } from "./chunk-EJMUO6VX.js";
5
5
  import {
6
6
  useAudioSync,
7
7
  useDocPlayback,
@@ -185,6 +185,7 @@ function MediaClipElement({
185
185
  src,
186
186
  preload: "auto",
187
187
  "data-clip-id": clip.id,
188
+ "data-active": active ? "true" : "false",
188
189
  "data-abs-start": clip.absoluteStart,
189
190
  "data-abs-end": clip.absoluteEnd,
190
191
  "data-source-in": clip.sourceIn
@@ -195,7 +196,6 @@ function MediaClipElement({
195
196
  {
196
197
  ...common,
197
198
  className: `doc-player__media-video${active ? " doc-player__media-video--active" : ""}`,
198
- "data-active": active ? "true" : "false",
199
199
  "data-video-placement": clip.placement ?? "default",
200
200
  muted: renderMode || muted,
201
201
  playsInline: true,
@@ -1757,6 +1757,27 @@ function DocPlayerContent({
1757
1757
  () => resolveMediaSchedule(doc, { intrinsicDuration: (clip) => clipDurations.get(clip.src) }),
1758
1758
  [doc, clipDurations]
1759
1759
  );
1760
+ const startActiveTimelineMedia = useCallback4(() => {
1761
+ if (renderMode) return;
1762
+ const root = containerRef.current;
1763
+ if (!root) return;
1764
+ const activeMedia = root.querySelectorAll(
1765
+ '.doc-player__block--active video[data-clip-start], [data-clip-id][data-active="true"]'
1766
+ );
1767
+ activeMedia.forEach((element) => {
1768
+ const playPromise = element.play();
1769
+ if (playPromise) playPromise.catch(() => {
1770
+ });
1771
+ });
1772
+ }, [renderMode]);
1773
+ const playWithTimelineMedia = useCallback4(() => {
1774
+ startActiveTimelineMedia();
1775
+ return play();
1776
+ }, [play, startActiveTimelineMedia]);
1777
+ const toggleWithTimelineMedia = useCallback4(() => {
1778
+ if (!isPlaying) startActiveTimelineMedia();
1779
+ return toggle();
1780
+ }, [isPlaying, startActiveTimelineMedia, toggle]);
1760
1781
  const currentTimeRef = useRef5(currentTime);
1761
1782
  currentTimeRef.current = currentTime;
1762
1783
  const committedRenderTimeRef = useRef5(currentTime);
@@ -1803,13 +1824,13 @@ function DocPlayerContent({
1803
1824
  ))
1804
1825
  return;
1805
1826
  containerRef.current?.focus({ preventScroll: true });
1806
- toggle();
1827
+ toggleWithTimelineMedia();
1807
1828
  const nextState = isPlaying ? "pause" : "play";
1808
1829
  setTapFeedback(nextState);
1809
1830
  clearTimeout(tapFeedbackTimer.current);
1810
1831
  tapFeedbackTimer.current = setTimeout(() => setTapFeedback(null), 600);
1811
1832
  },
1812
- [renderMode, toggle, isPlaying, isSlideshowMode, isLinearMode]
1833
+ [renderMode, toggleWithTimelineMedia, isPlaying, isSlideshowMode, isLinearMode]
1813
1834
  );
1814
1835
  const autoSurface = useAutoSurface(surface === "auto");
1815
1836
  const resolvedSurface = surface === "auto" ? autoSurface : surface;
@@ -1932,9 +1953,9 @@ function DocPlayerContent({
1932
1953
  useEffect5(() => {
1933
1954
  if (isAudioReady && autoPlay && !hasAutoPlayed.current) {
1934
1955
  hasAutoPlayed.current = true;
1935
- play();
1956
+ playWithTimelineMedia();
1936
1957
  }
1937
- }, [isAudioReady, autoPlay, play]);
1958
+ }, [isAudioReady, autoPlay, playWithTimelineMedia]);
1938
1959
  useEffect5(() => {
1939
1960
  onTimeUpdate?.(currentTime);
1940
1961
  }, [currentTime, onTimeUpdate]);
@@ -2173,14 +2194,21 @@ function DocPlayerContent({
2173
2194
  );
2174
2195
  const playbackActions = useMemo3(
2175
2196
  () => ({
2176
- toggle,
2197
+ toggle: toggleWithTimelineMedia,
2177
2198
  restart,
2178
2199
  seekTo,
2179
2200
  setCaptionsEnabled,
2180
2201
  cycleCaptionMode,
2181
2202
  toggleFullscreen: onFullscreenToggle
2182
2203
  }),
2183
- [toggle, restart, seekTo, setCaptionsEnabled, cycleCaptionMode, onFullscreenToggle]
2204
+ [
2205
+ toggleWithTimelineMedia,
2206
+ restart,
2207
+ seekTo,
2208
+ setCaptionsEnabled,
2209
+ cycleCaptionMode,
2210
+ onFullscreenToggle
2211
+ ]
2184
2212
  );
2185
2213
  const slideNavActions = useMemo3(
2186
2214
  () => ({
@@ -2275,8 +2303,8 @@ function DocPlayerContent({
2275
2303
  onPlaybackStateChange?.(playbackState);
2276
2304
  }, [playbackState, onPlaybackStateChange]);
2277
2305
  useEffect5(() => {
2278
- onControlsReady?.({ play, pause, ...playbackActions });
2279
- }, [play, pause, playbackActions, onControlsReady]);
2306
+ onControlsReady?.({ play: playWithTimelineMedia, pause, ...playbackActions });
2307
+ }, [playWithTimelineMedia, pause, playbackActions, onControlsReady]);
2280
2308
  const getBlockTitle = useCallback4((block) => {
2281
2309
  const docBlock = block;
2282
2310
  if (isTemplateBlock2(docBlock)) {
@@ -2390,7 +2418,7 @@ function DocPlayerContent({
2390
2418
  switch (e.key) {
2391
2419
  case " ":
2392
2420
  e.preventDefault();
2393
- toggle();
2421
+ toggleWithTimelineMedia();
2394
2422
  break;
2395
2423
  case "ArrowRight":
2396
2424
  e.preventDefault();
@@ -2403,7 +2431,14 @@ function DocPlayerContent({
2403
2431
  }
2404
2432
  }
2405
2433
  },
2406
- [isSlideshowMode, isLinearMode, toggle, seekTo, slideNavActions, onFullscreenToggle]
2434
+ [
2435
+ isSlideshowMode,
2436
+ isLinearMode,
2437
+ toggleWithTimelineMedia,
2438
+ seekTo,
2439
+ slideNavActions,
2440
+ onFullscreenToggle
2441
+ ]
2407
2442
  );
2408
2443
  const handleKeyDown = useCallback4(
2409
2444
  (e) => handleKeyboardShortcut(e, false),
@@ -2498,6 +2533,7 @@ function DocPlayerContent({
2498
2533
  basePath,
2499
2534
  isEntering: false,
2500
2535
  viewport: activeViewport,
2536
+ muted: renderMode || muted,
2501
2537
  animationsEnabled,
2502
2538
  theme: effectiveTheme
2503
2539
  }
@@ -2515,15 +2551,20 @@ function DocPlayerContent({
2515
2551
  isExiting: true,
2516
2552
  transition: currentBlock?.transition,
2517
2553
  viewport: activeViewport,
2554
+ muted: renderMode || muted,
2518
2555
  animationsEnabled,
2519
2556
  theme: effectiveTheme
2520
2557
  }
2521
2558
  ) }, previousBlock.id),
2522
- !showCoverBlock && currentBlock && /* @__PURE__ */ jsx7(
2559
+ currentBlock && /* @__PURE__ */ jsx7(
2523
2560
  "div",
2524
2561
  {
2525
2562
  className: `doc-player__block doc-player__block--active${swipe.phase !== "idle" ? ` doc-player__block--${swipe.phase}` : ""}`,
2526
- style: swipe.phase !== "idle" ? { transform: `translateX(${swipe.offsetPx}px)` } : void 0,
2563
+ "aria-hidden": showCoverBlock || void 0,
2564
+ style: showCoverBlock || swipe.phase !== "idle" ? {
2565
+ ...swipe.phase !== "idle" ? { transform: `translateX(${swipe.offsetPx}px)` } : {},
2566
+ ...showCoverBlock ? { opacity: 0, pointerEvents: "none" } : {}
2567
+ } : void 0,
2527
2568
  children: /* @__PURE__ */ jsx7(
2528
2569
  BlockRenderer,
2529
2570
  {
@@ -2533,6 +2574,7 @@ function DocPlayerContent({
2533
2574
  isEntering: animationsEnabled && isEntering,
2534
2575
  viewport: activeViewport,
2535
2576
  isPlaying,
2577
+ muted: renderMode || muted,
2536
2578
  animationsEnabled,
2537
2579
  theme: effectiveTheme
2538
2580
  }
@@ -9,7 +9,7 @@ import {
9
9
  TreeLayer,
10
10
  VideoLayer,
11
11
  getTransitionClass
12
- } from "./chunk-XYS7HMP4.js";
12
+ } from "./chunk-TI5X7SBC.js";
13
13
  import {
14
14
  useAutoSurface
15
15
  } from "./chunk-TT6ENR6T.js";
@@ -38,6 +38,7 @@ function BlockRenderer({
38
38
  transition,
39
39
  viewport = DEFAULT_VIEWPORT,
40
40
  isPlaying,
41
+ muted = false,
41
42
  animationsEnabled = true,
42
43
  theme
43
44
  }) {
@@ -72,6 +73,7 @@ function BlockRenderer({
72
73
  viewport,
73
74
  blockTime,
74
75
  isPlaying,
76
+ muted,
75
77
  animationsEnabled,
76
78
  theme
77
79
  },
@@ -87,6 +89,7 @@ function LayerRenderer({
87
89
  viewport,
88
90
  blockTime,
89
91
  isPlaying,
92
+ muted,
90
93
  animationsEnabled,
91
94
  theme
92
95
  }) {
@@ -127,7 +130,8 @@ function LayerRenderer({
127
130
  basePath,
128
131
  viewport,
129
132
  blockTime,
130
- isPlaying
133
+ isPlaying,
134
+ muted
131
135
  }
132
136
  );
133
137
  case "table":
@@ -543,25 +543,41 @@ function RichTextLayer({ layer, viewport, blockTime }) {
543
543
  };
544
544
  const cls = `squisq-rich-text-${cssId(layer.id)}`;
545
545
  const scopedCss = `.${cls}{margin:0}.${cls} p{margin:0 0 .4em}.${cls} h1,.${cls} h2,.${cls} h3,.${cls} h4,.${cls} h5,.${cls} h6{margin:0 0 .3em;line-height:1.2}.${cls} ul,.${cls} ol{margin:0 0 .4em;padding-left:1.2em;list-style-position:inside}.${cls} li{margin:0}.${cls} li>p{display:inline;margin:0}.${cls} *:first-child{margin-top:0}.${cls} *:last-child{margin-bottom:0}.${cls} a{color:inherit;text-decoration:underline}`;
546
- return /* @__PURE__ */ jsx3("g", { className: `block-layer block-layer--text ${animStyle.className}`, "data-layer-id": layer.id, children: /* @__PURE__ */ jsx3("foreignObject", { x: boxX, y: boxY, width: boxWidth, height: boxHeight, children: /* @__PURE__ */ jsxs2(
547
- "div",
546
+ return /* @__PURE__ */ jsx3("g", { className: `block-layer block-layer--text ${animStyle.className}`, "data-layer-id": layer.id, children: /* @__PURE__ */ jsx3(
547
+ "foreignObject",
548
548
  {
549
- ...{ xmlns: "http://www.w3.org/1999/xhtml" },
550
- style: boxStyle,
551
- children: [
552
- /* @__PURE__ */ jsx3("style", { children: scopedCss }),
553
- /* @__PURE__ */ jsx3(
554
- "div",
555
- {
556
- className: cls,
557
- "aria-label": content.text,
558
- style: { width: "100%", whiteSpace: "pre-wrap", wordBreak: "break-word" },
559
- dangerouslySetInnerHTML: { __html: safeHtml }
560
- }
561
- )
562
- ]
549
+ x: boxX,
550
+ y: boxY,
551
+ width: boxWidth,
552
+ height: boxHeight,
553
+ color: style.color,
554
+ style: { color: style.color },
555
+ children: /* @__PURE__ */ jsxs2(
556
+ "div",
557
+ {
558
+ ...{ xmlns: "http://www.w3.org/1999/xhtml" },
559
+ style: boxStyle,
560
+ children: [
561
+ /* @__PURE__ */ jsx3("style", { children: scopedCss }),
562
+ /* @__PURE__ */ jsx3(
563
+ "div",
564
+ {
565
+ className: cls,
566
+ "aria-label": content.text,
567
+ style: {
568
+ width: "100%",
569
+ color: style.color,
570
+ whiteSpace: "pre-wrap",
571
+ wordBreak: "break-word"
572
+ },
573
+ dangerouslySetInnerHTML: { __html: safeHtml }
574
+ }
575
+ )
576
+ ]
577
+ }
578
+ )
563
579
  }
564
- ) }) });
580
+ ) });
565
581
  }
566
582
  function cssId(id) {
567
583
  return id.replace(/[^a-zA-Z0-9_-]/g, "-");
@@ -1229,7 +1245,14 @@ function MapLayer({ layer, basePath, viewport, blockTime }) {
1229
1245
  import { useRef, useEffect as useEffect2 } from "react";
1230
1246
  import { jsx as jsx7 } from "react/jsx-runtime";
1231
1247
  var VIDEO_SYNC_DRIFT_SECONDS = 0.2;
1232
- function VideoLayer({ layer, basePath, viewport, blockTime, isPlaying }) {
1248
+ function VideoLayer({
1249
+ layer,
1250
+ basePath,
1251
+ viewport,
1252
+ blockTime,
1253
+ isPlaying,
1254
+ muted = false
1255
+ }) {
1233
1256
  const { content, position } = layer;
1234
1257
  const videoRef = useRef(null);
1235
1258
  const hasStartedRef = useRef(false);
@@ -1300,7 +1323,7 @@ function VideoLayer({ layer, basePath, viewport, blockTime, isPlaying }) {
1300
1323
  ref: videoRef,
1301
1324
  src,
1302
1325
  poster: posterSrc,
1303
- muted: true,
1326
+ muted,
1304
1327
  playsInline: true,
1305
1328
  preload: "auto",
1306
1329
  "data-clip-start": content.clipStart,
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  formatTime,
13
13
  resolveDocPlayerAppearance,
14
14
  useMediaClipDurations
15
- } from "./chunk-EKD6JMJN.js";
15
+ } from "./chunk-7YFNL63X.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-M2HEFJZP.js";
23
+ } from "./chunk-EJMUO6VX.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-XYS7HMP4.js";
36
+ } from "./chunk-TI5X7SBC.js";
37
37
  import {
38
38
  useModalDialog
39
39
  } from "./chunk-65POMKHR.js";
@@ -70,8 +70,10 @@ interface VideoLayerProps {
70
70
  blockTime: number;
71
71
  /** Whether the doc is currently playing */
72
72
  isPlaying?: boolean;
73
+ /** Silence the video's own audio track. */
74
+ muted?: boolean;
73
75
  }
74
- declare function VideoLayer({ layer, basePath, viewport, blockTime, isPlaying }: VideoLayerProps): react_jsx_runtime.JSX.Element;
76
+ declare function VideoLayer({ layer, basePath, viewport, blockTime, isPlaying, muted, }: VideoLayerProps): react_jsx_runtime.JSX.Element;
75
77
 
76
78
  interface TableLayerProps {
77
79
  layer: TableLayer$1;
@@ -8,7 +8,7 @@ import {
8
8
  TextLayer,
9
9
  TreeLayer,
10
10
  VideoLayer
11
- } from "../chunk-XYS7HMP4.js";
11
+ } from "../chunk-TI5X7SBC.js";
12
12
  import "../chunk-WLUZTUNZ.js";
13
13
  import "../chunk-LR3AIGDD.js";
14
14
  export {
@@ -4,8 +4,8 @@ import {
4
4
  PageSectionView,
5
5
  PageViewContext,
6
6
  usePageView
7
- } from "../chunk-M2HEFJZP.js";
8
- import "../chunk-XYS7HMP4.js";
7
+ } from "../chunk-EJMUO6VX.js";
8
+ import "../chunk-TI5X7SBC.js";
9
9
  import "../chunk-TT6ENR6T.js";
10
10
  import "../chunk-D7KN4CRG.js";
11
11
  import "../chunk-WLUZTUNZ.js";
@@ -269,6 +269,8 @@ interface BlockRendererProps {
269
269
  viewport?: ViewportDimensions;
270
270
  /** Whether the doc is currently playing (controls video playback) */
271
271
  isPlaying?: boolean;
272
+ /** Silence audio carried by video layers. */
273
+ muted?: boolean;
272
274
  /**
273
275
  * Whether to render block transitions and layer animations (default: true).
274
276
  * Disabling this only removes authored/render-style motion; timed video
@@ -278,7 +280,7 @@ interface BlockRendererProps {
278
280
  /** Resolved theme inherited by rich-media renderers such as Mermaid. */
279
281
  theme?: Theme;
280
282
  }
281
- declare function BlockRenderer({ block, blockTime, basePath, isEntering, isExiting, transition, viewport, isPlaying, animationsEnabled, theme, }: BlockRendererProps): react_jsx_runtime.JSX.Element;
283
+ declare function BlockRenderer({ block, blockTime, basePath, isEntering, isExiting, transition, viewport, isPlaying, muted, animationsEnabled, theme, }: BlockRendererProps): react_jsx_runtime.JSX.Element;
282
284
 
283
285
  interface CaptionOverlayProps {
284
286
  /** Caption track with timestamped phrases */
@@ -10,11 +10,11 @@ import {
10
10
  MediaClipLayer,
11
11
  SocialCaptionOverlay,
12
12
  formatTime
13
- } from "../chunk-EKD6JMJN.js";
13
+ } from "../chunk-7YFNL63X.js";
14
14
  import {
15
15
  BlockRenderer
16
- } from "../chunk-M2HEFJZP.js";
17
- import "../chunk-XYS7HMP4.js";
16
+ } from "../chunk-EJMUO6VX.js";
17
+ import "../chunk-TI5X7SBC.js";
18
18
  import "../chunk-BOZJ655L.js";
19
19
  import "../chunk-TT6ENR6T.js";
20
20
  import {