@bendyline/squisq-react 2.11.2 → 2.11.4

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.
@@ -365,7 +365,7 @@ function iconRunsToHtml(text) {
365
365
  (run) => run.type === "icon" ? `<i class="${iconClass(run.family, run.name)}" aria-hidden="true"></i>` : escapeHtml(run.text).replace(/\n/g, "<br>")
366
366
  ).join("");
367
367
  }
368
- function IconTextLayer({ layer, viewport, blockTime }) {
368
+ function IconTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
369
369
  const { content, position, animation } = layer;
370
370
  const { text, style } = content;
371
371
  const rawX = resolveValue(position.x, viewport.width);
@@ -392,7 +392,7 @@ function IconTextLayer({ layer, viewport, blockTime }) {
392
392
  justifyContent: verticalJustify,
393
393
  padding,
394
394
  color: style.color,
395
- fontSize: `${style.fontSize}px`,
395
+ fontSize: `${style.fontSize * textScale}px`,
396
396
  fontFamily: style.fontFamily || DEFAULT_DOC_FONT,
397
397
  fontWeight: style.fontWeight || "normal",
398
398
  fontStyle: style.fontStyle || "normal",
@@ -413,10 +413,13 @@ function IconTextLayer({ layer, viewport, blockTime }) {
413
413
  "div",
414
414
  {
415
415
  ...{ xmlns: "http://www.w3.org/1999/xhtml" },
416
+ "data-squisq-text-fit": "html",
417
+ "data-squisq-base-font-size": style.fontSize,
416
418
  style: boxStyle,
417
419
  children: /* @__PURE__ */ jsx3(
418
420
  "div",
419
421
  {
422
+ "data-squisq-text-content": "true",
420
423
  style: { width: "100%", whiteSpace: "pre-wrap", wordBreak: "break-word" },
421
424
  "aria-label": plain,
422
425
  dangerouslySetInnerHTML: { __html: html }
@@ -427,7 +430,7 @@ function IconTextLayer({ layer, viewport, blockTime }) {
427
430
  }
428
431
  ) });
429
432
  }
430
- function PlainTextLayer({ layer, viewport, blockTime }) {
433
+ function PlainTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
431
434
  const defsId = `${useId().replace(/:/g, "")}-${layer.id}`;
432
435
  const { content, position, animation } = layer;
433
436
  const { text, style } = content;
@@ -441,6 +444,8 @@ function PlainTextLayer({ layer, viewport, blockTime }) {
441
444
  const anchor = position.anchor ?? "top-left";
442
445
  const x = pivotX(rawX, boxWidth, anchor, textAnchor);
443
446
  const y = pivotY(rawY, boxHeight, anchor, dominantBaseline);
447
+ const fitWidth = boxWidth ?? (textAnchor === "middle" ? Math.max(0, Math.min(x, viewport.width - x) * 2) : textAnchor === "end" ? Math.max(0, x) : Math.max(0, viewport.width - x));
448
+ const fitHeight = boxHeight ?? (dominantBaseline === "middle" ? Math.max(0, Math.min(y, viewport.height - y) * 2) : dominantBaseline === "text-after-edge" ? Math.max(0, y) : Math.max(0, viewport.height - y));
444
449
  const animStyle = getAnimationStyle(animation, blockTime);
445
450
  const rawLines = (text ?? "").split("\n");
446
451
  let lines = maxWidth ? rawLines.reduce(
@@ -533,25 +538,39 @@ function PlainTextLayer({ layer, viewport, blockTime }) {
533
538
  }
534
539
  ),
535
540
  /* @__PURE__ */ jsx3(
536
- "text",
541
+ "g",
537
542
  {
538
- ref: textRef,
539
- x,
540
- y,
541
- textAnchor,
542
- dominantBaseline,
543
- style: textStyles,
544
- filter: filterId ? `url(#${filterId})` : void 0,
545
- transform: fitTransform,
546
- children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tspan", { x, dy: i === 0 ? firstLineDy : lineHeightPx, children: [
547
- line || "\xA0",
548
- " "
549
- ] }, i))
543
+ "data-squisq-text-fit": "svg",
544
+ "data-squisq-fit-width": fitWidth,
545
+ "data-squisq-fit-height": fitHeight,
546
+ style: {
547
+ transform: `scale(${textScale})`,
548
+ transformOrigin: `${x}px ${y}px`,
549
+ transformBox: "view-box"
550
+ },
551
+ children: /* @__PURE__ */ jsx3(
552
+ "text",
553
+ {
554
+ ref: textRef,
555
+ "data-squisq-text-content": "true",
556
+ x,
557
+ y,
558
+ textAnchor,
559
+ dominantBaseline,
560
+ style: textStyles,
561
+ filter: filterId ? `url(#${filterId})` : void 0,
562
+ transform: fitTransform,
563
+ children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tspan", { x, dy: i === 0 ? firstLineDy : lineHeightPx, children: [
564
+ line || "\xA0",
565
+ " "
566
+ ] }, i))
567
+ }
568
+ )
550
569
  }
551
570
  )
552
571
  ] });
553
572
  }
554
- function RichTextLayer({ layer, viewport, blockTime }) {
573
+ function RichTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
555
574
  const { content, position, animation } = layer;
556
575
  const { html, style } = content;
557
576
  const rawX = resolveValue(position.x, viewport.width);
@@ -577,7 +596,7 @@ function RichTextLayer({ layer, viewport, blockTime }) {
577
596
  justifyContent: verticalJustify,
578
597
  padding: style.padding ?? 0,
579
598
  color: style.color,
580
- fontSize: `${style.fontSize}px`,
599
+ fontSize: `${style.fontSize * textScale}px`,
581
600
  fontFamily: style.fontFamily || DEFAULT_DOC_FONT,
582
601
  fontWeight: style.fontWeight || "normal",
583
602
  fontStyle: style.fontStyle || "normal",
@@ -594,7 +613,11 @@ function RichTextLayer({ layer, viewport, blockTime }) {
594
613
  };
595
614
  const cls = `squisq-rich-text-${cssId(layer.id)}`;
596
615
  const listStylePosition = style.textAlign === "center" || style.textAlign === "right" ? "inside" : "outside";
597
- 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 .7em;padding-left:1.2em;list-style-position:${listStylePosition}}.${cls} li{margin:0}.${cls} li>p{display:inline;margin:0}.${cls} table{width:100%;margin:.65em 0;border-collapse:collapse;border-spacing:0;table-layout:fixed}.${cls} th,.${cls} td{box-sizing:border-box;padding:.38em .55em;border:1px solid rgba(127,127,127,.55);border-color:color-mix(in srgb,currentColor 32%,transparent);vertical-align:top;white-space:normal;overflow-wrap:anywhere}.${cls} th{background:rgba(127,127,127,.16);background:color-mix(in srgb,currentColor 12%,transparent);font-weight:600}.${cls} tbody tr:nth-child(even){background:rgba(127,127,127,.07);background:color-mix(in srgb,currentColor 5%,transparent)}.${cls} *:first-child{margin-top:0}.${cls} *:last-child{margin-bottom:0}.${cls} a{color:inherit;text-decoration:underline}`;
616
+ const stopEmbeddedTableEvent = (event) => {
617
+ const target = event.target;
618
+ if (target?.closest?.("[data-squisq-table-scroll]")) event.stopPropagation();
619
+ };
620
+ 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 .7em;padding-left:1.2em;list-style-position:${listStylePosition}}.${cls} li{margin:0}.${cls} li>p{display:inline;margin:0}.${cls} [data-squisq-table-scroll]{width:100%;max-height:20em;margin:.35em 0;overflow:auto;overscroll-behavior:contain;box-sizing:border-box}.${cls} table{width:100%;min-width:48em;margin:0;border-collapse:separate;border-spacing:0;table-layout:fixed;font-size:.76em;line-height:1.2}.${cls} th,.${cls} td{box-sizing:border-box;padding:.28em .45em;border:1px solid rgba(127,127,127,.55);border-color:color-mix(in srgb,currentColor 32%,transparent);vertical-align:top;white-space:normal;overflow-wrap:anywhere}.${cls} th{position:sticky;top:0;z-index:1;background:rgba(127,127,127,.16);background:color-mix(in srgb,currentColor 12%,transparent);font-weight:600}.${cls} tbody tr:nth-child(even){background:rgba(127,127,127,.07);background:color-mix(in srgb,currentColor 5%,transparent)}.${cls} *:first-child{margin-top:0}.${cls} *:last-child{margin-bottom:0}.${cls} a{color:inherit;text-decoration:underline}`;
598
621
  return /* @__PURE__ */ jsx3("g", { className: `block-layer block-layer--text ${animStyle.className}`, "data-layer-id": layer.id, children: /* @__PURE__ */ jsx3(
599
622
  "foreignObject",
600
623
  {
@@ -608,12 +631,19 @@ function RichTextLayer({ layer, viewport, blockTime }) {
608
631
  "div",
609
632
  {
610
633
  ...{ xmlns: "http://www.w3.org/1999/xhtml" },
634
+ "data-squisq-text-fit": "html",
635
+ "data-squisq-base-font-size": style.fontSize,
611
636
  style: boxStyle,
637
+ onPointerDown: stopEmbeddedTableEvent,
638
+ onClick: stopEmbeddedTableEvent,
639
+ onWheel: stopEmbeddedTableEvent,
640
+ onKeyDown: stopEmbeddedTableEvent,
612
641
  children: [
613
642
  /* @__PURE__ */ jsx3("style", { children: scopedCss }),
614
643
  /* @__PURE__ */ jsx3(
615
644
  "div",
616
645
  {
646
+ "data-squisq-text-content": "true",
617
647
  className: cls,
618
648
  "aria-label": content.text,
619
649
  style: {
@@ -761,25 +791,31 @@ function ShapeLayer({ layer, viewport, blockTime }) {
761
791
  const fill = content.fill || "none";
762
792
  const isCSSGradient = typeof fill === "string" && fill.includes("gradient(");
763
793
  if (content.shape === "rect" && isCSSGradient && !content.gradient) {
764
- return /* @__PURE__ */ jsx4(
765
- "g",
766
- {
767
- className: `block-layer block-layer--shape ${animStyle.className}`,
768
- style: animStyle.style,
769
- "data-layer-id": layer.id,
770
- children: /* @__PURE__ */ jsx4("foreignObject", { x: paintX, y: paintY, width: paintWidth, height: paintHeight, children: /* @__PURE__ */ jsx4(
771
- "div",
772
- {
773
- style: {
774
- width: `${paintWidth}px`,
775
- height: `${paintHeight}px`,
776
- background: fill,
777
- borderRadius: content.borderRadius ? `${content.borderRadius}px` : void 0,
778
- pointerEvents: "none"
794
+ return (
795
+ // Shape layers are visual primitives. In particular, theme top-layers
796
+ // can cover the whole slide; they must not shield interactive table,
797
+ // map, or media layers underneath them from pointer/wheel input.
798
+ /* @__PURE__ */ jsx4(
799
+ "g",
800
+ {
801
+ className: `block-layer block-layer--shape ${animStyle.className}`,
802
+ style: animStyle.style,
803
+ "data-layer-id": layer.id,
804
+ pointerEvents: "none",
805
+ children: /* @__PURE__ */ jsx4("foreignObject", { x: paintX, y: paintY, width: paintWidth, height: paintHeight, children: /* @__PURE__ */ jsx4(
806
+ "div",
807
+ {
808
+ style: {
809
+ width: `${paintWidth}px`,
810
+ height: `${paintHeight}px`,
811
+ background: fill,
812
+ borderRadius: content.borderRadius ? `${content.borderRadius}px` : void 0,
813
+ pointerEvents: "none"
814
+ }
779
815
  }
780
- }
781
- ) })
782
- }
816
+ ) })
817
+ }
818
+ )
783
819
  );
784
820
  }
785
821
  const { fill: fillValue, def: fillDef } = resolveFill(
@@ -798,52 +834,57 @@ function ShapeLayer({ layer, viewport, blockTime }) {
798
834
  strokeDasharray: dash,
799
835
  ...filterAttr ? { filter: filterAttr } : {}
800
836
  };
801
- return /* @__PURE__ */ jsxs3(
802
- "g",
803
- {
804
- className: `block-layer block-layer--shape ${animStyle.className}`,
805
- style: animStyle.style,
806
- "data-layer-id": layer.id,
807
- children: [
808
- (fillDef || filterDef) && /* @__PURE__ */ jsxs3("defs", { children: [
809
- fillDef,
810
- filterDef
811
- ] }),
812
- content.shape === "rect" && /* @__PURE__ */ jsx4(
813
- "rect",
814
- {
815
- x: paintX,
816
- y: paintY,
817
- width: paintWidth,
818
- height: paintHeight,
819
- rx: content.borderRadius,
820
- ry: content.borderRadius,
821
- ...shapeProps
822
- }
823
- ),
824
- content.shape === "circle" && /* @__PURE__ */ jsx4(
825
- "circle",
826
- {
827
- cx: x + width / 2,
828
- cy: y + height / 2,
829
- r: Math.min(width, height) / 2,
830
- ...shapeProps
831
- }
832
- ),
833
- content.shape === "line" && /* @__PURE__ */ jsx4(
834
- "line",
835
- {
836
- x1: x,
837
- y1: y,
838
- x2: x + width,
839
- y2: y + height,
840
- stroke: content.stroke || "#ffffff",
841
- strokeWidth: content.strokeWidth || 2,
842
- strokeDasharray: dash
843
- }
844
- )
845
- ]
846
- }
837
+ return (
838
+ // Native SVG shapes follow the same visual-only interaction contract as
839
+ // the foreignObject gradient branch above.
840
+ /* @__PURE__ */ jsxs3(
841
+ "g",
842
+ {
843
+ className: `block-layer block-layer--shape ${animStyle.className}`,
844
+ style: animStyle.style,
845
+ "data-layer-id": layer.id,
846
+ pointerEvents: "none",
847
+ children: [
848
+ (fillDef || filterDef) && /* @__PURE__ */ jsxs3("defs", { children: [
849
+ fillDef,
850
+ filterDef
851
+ ] }),
852
+ content.shape === "rect" && /* @__PURE__ */ jsx4(
853
+ "rect",
854
+ {
855
+ x: paintX,
856
+ y: paintY,
857
+ width: paintWidth,
858
+ height: paintHeight,
859
+ rx: content.borderRadius,
860
+ ry: content.borderRadius,
861
+ ...shapeProps
862
+ }
863
+ ),
864
+ content.shape === "circle" && /* @__PURE__ */ jsx4(
865
+ "circle",
866
+ {
867
+ cx: x + width / 2,
868
+ cy: y + height / 2,
869
+ r: Math.min(width, height) / 2,
870
+ ...shapeProps
871
+ }
872
+ ),
873
+ content.shape === "line" && /* @__PURE__ */ jsx4(
874
+ "line",
875
+ {
876
+ x1: x,
877
+ y1: y,
878
+ x2: x + width,
879
+ y2: y + height,
880
+ stroke: content.stroke || "#ffffff",
881
+ strokeWidth: content.strokeWidth || 2,
882
+ strokeDasharray: dash
883
+ }
884
+ )
885
+ ]
886
+ }
887
+ )
847
888
  );
848
889
  }
849
890
 
@@ -1395,9 +1436,17 @@ function VideoLayer({
1395
1436
 
1396
1437
  // src/layers/TableLayer.tsx
1397
1438
  import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1398
- function TableLayer({ layer, viewport, blockTime }) {
1439
+ function TableLayer({
1440
+ block,
1441
+ layer,
1442
+ viewport,
1443
+ blockTime,
1444
+ contentRenderer
1445
+ }) {
1399
1446
  const { content, position, animation } = layer;
1400
- const { headers, rows, align, style } = content;
1447
+ const { align, style } = content;
1448
+ const headers = Array.isArray(content.headers) ? content.headers : [];
1449
+ const rows = Array.isArray(content.rows) ? content.rows : [];
1401
1450
  const x = resolveValue(position.x, viewport.width);
1402
1451
  const y = resolveValue(position.y, viewport.height);
1403
1452
  const width = position.width ? resolveValue(position.width, viewport.width) : viewport.width;
@@ -1411,6 +1460,62 @@ function TableLayer({ layer, viewport, blockTime }) {
1411
1460
  return a ? { textAlign: a } : void 0;
1412
1461
  };
1413
1462
  const borderRadius = style.borderRadius ?? 8;
1463
+ const verticalCellPadding = style.fontSize * 0.6;
1464
+ const horizontalCellPadding = style.fontSize * 0.75;
1465
+ const nativeTable = /* @__PURE__ */ jsxs6(
1466
+ "table",
1467
+ {
1468
+ style: {
1469
+ width: "max-content",
1470
+ minWidth: "100%",
1471
+ borderCollapse: "separate",
1472
+ borderSpacing: 0,
1473
+ fontSize: `${style.fontSize}px`,
1474
+ fontFamily: style.fontFamily ?? "system-ui, sans-serif",
1475
+ lineHeight: 1.2
1476
+ },
1477
+ children: [
1478
+ headers.length > 0 && /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsx8("tr", { children: headers.map((header, ci) => /* @__PURE__ */ jsx8(
1479
+ "th",
1480
+ {
1481
+ style: {
1482
+ background: style.headerBackground,
1483
+ color: style.headerColor,
1484
+ fontFamily: style.headerFontFamily ?? style.fontFamily ?? "system-ui, sans-serif",
1485
+ fontWeight: 600,
1486
+ padding: `${verticalCellPadding}px ${horizontalCellPadding}px`,
1487
+ position: "sticky",
1488
+ top: 0,
1489
+ zIndex: 1,
1490
+ whiteSpace: "nowrap",
1491
+ borderBottom: `2px solid ${style.borderColor}`,
1492
+ borderRight: ci < headers.length - 1 ? `1px solid ${style.borderColor}` : void 0,
1493
+ ...cellAlign(ci)
1494
+ },
1495
+ children: header
1496
+ },
1497
+ ci
1498
+ )) }) }),
1499
+ rows.length > 0 && /* @__PURE__ */ jsx8("tbody", { children: rows.map((row, ri) => /* @__PURE__ */ jsx8("tr", { children: row.map((cell, ci) => /* @__PURE__ */ jsx8(
1500
+ "td",
1501
+ {
1502
+ style: {
1503
+ background: style.cellBackground,
1504
+ color: style.cellColor,
1505
+ padding: `${verticalCellPadding}px ${horizontalCellPadding}px`,
1506
+ whiteSpace: "nowrap",
1507
+ borderBottom: ri < rows.length - 1 ? `1px solid ${style.borderColor}` : void 0,
1508
+ borderRight: ci < row.length - 1 ? `1px solid ${style.borderColor}` : void 0,
1509
+ ...cellAlign(ci)
1510
+ },
1511
+ children: cell
1512
+ },
1513
+ ci
1514
+ )) }, ri)) })
1515
+ ]
1516
+ }
1517
+ );
1518
+ const ContentRenderer = block ? contentRenderer : void 0;
1414
1519
  return /* @__PURE__ */ jsx8(
1415
1520
  "g",
1416
1521
  {
@@ -1421,64 +1526,35 @@ function TableLayer({ layer, viewport, blockTime }) {
1421
1526
  "div",
1422
1527
  {
1423
1528
  ...{ xmlns: "http://www.w3.org/1999/xhtml" },
1529
+ className: "squisq-table-scroll",
1530
+ role: "region",
1531
+ "aria-label": "Scrollable data table",
1532
+ tabIndex: 0,
1533
+ onPointerDown: (event) => event.stopPropagation(),
1534
+ onClick: (event) => event.stopPropagation(),
1535
+ onWheel: (event) => event.stopPropagation(),
1536
+ onKeyDown: (event) => event.stopPropagation(),
1424
1537
  style: {
1425
1538
  width: `${width}px`,
1426
1539
  height: `${height}px`,
1427
- display: "flex",
1428
- alignItems: "center",
1429
- justifyContent: "center",
1430
- padding: "16px",
1431
- boxSizing: "border-box"
1540
+ boxSizing: "border-box",
1541
+ overflow: ContentRenderer ? "hidden" : "auto",
1542
+ overscrollBehavior: "contain",
1543
+ scrollbarGutter: "stable",
1544
+ border: ContentRenderer ? void 0 : `1px solid ${style.borderColor}`,
1545
+ borderRadius: `${borderRadius}px`,
1546
+ background: ContentRenderer ? "transparent" : style.cellBackground
1432
1547
  },
1433
- children: /* @__PURE__ */ jsxs6(
1434
- "table",
1548
+ children: ContentRenderer ? /* @__PURE__ */ jsx8(
1549
+ ContentRenderer,
1435
1550
  {
1436
- style: {
1437
- width: "100%",
1438
- borderCollapse: "separate",
1439
- borderSpacing: 0,
1440
- fontSize: `${style.fontSize}px`,
1441
- fontFamily: style.fontFamily ?? "system-ui, sans-serif",
1442
- overflow: "hidden",
1443
- borderRadius: `${borderRadius}px`,
1444
- border: `1px solid ${style.borderColor}`
1445
- },
1446
- children: [
1447
- headers.length > 0 && /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsx8("tr", { children: headers.map((header, ci) => /* @__PURE__ */ jsx8(
1448
- "th",
1449
- {
1450
- style: {
1451
- background: style.headerBackground,
1452
- color: style.headerColor,
1453
- fontFamily: style.headerFontFamily ?? style.fontFamily ?? "system-ui, sans-serif",
1454
- fontWeight: 600,
1455
- padding: "12px 16px",
1456
- borderBottom: `2px solid ${style.borderColor}`,
1457
- borderRight: ci < headers.length - 1 ? `1px solid ${style.borderColor}` : void 0,
1458
- ...cellAlign(ci)
1459
- },
1460
- children: header
1461
- },
1462
- ci
1463
- )) }) }),
1464
- rows.length > 0 && /* @__PURE__ */ jsx8("tbody", { children: rows.map((row, ri) => /* @__PURE__ */ jsx8("tr", { children: row.map((cell, ci) => /* @__PURE__ */ jsx8(
1465
- "td",
1466
- {
1467
- style: {
1468
- background: style.cellBackground,
1469
- color: style.cellColor,
1470
- padding: "10px 16px",
1471
- borderBottom: ri < rows.length - 1 ? `1px solid ${style.borderColor}` : void 0,
1472
- borderRight: ci < row.length - 1 ? `1px solid ${style.borderColor}` : void 0,
1473
- ...cellAlign(ci)
1474
- },
1475
- children: cell
1476
- },
1477
- ci
1478
- )) }, ri)) })
1479
- ]
1551
+ block,
1552
+ layer,
1553
+ width,
1554
+ height,
1555
+ fallback: nativeTable
1480
1556
  }
1481
- )
1557
+ ) : nativeTable
1482
1558
  }
1483
1559
  ) })
1484
1560
  }
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as SquisqRenderAPI, V as VideoPresentation$1, P as PipSize, a as PipShape, b as PipPosition } from './player-DSMhm8SL.js';
2
- export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, e as CaptionPosition, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, E as SlideNavActions, G as SocialCaptionOverlay, H as formatTime } from './player-DSMhm8SL.js';
1
+ import { S as SquisqRenderAPI, V as VideoPresentation$1, P as PipSize, a as PipShape, b as PipPosition } from './player-BlD8zREs.js';
2
+ export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, e as CaptionPosition, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, E as SlideNavActions, G as SocialCaptionOverlay, H as formatTime } from './player-BlD8zREs.js';
3
3
  import { Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, ScheduledClip, MediaProvider } from '@bendyline/squisq/schemas';
4
4
  import { DashboardStyleId, ViewportConfig, CoverSlideTemplate, CoverSlidePlayback } from '@bendyline/squisq/doc';
5
5
  export { getAnimationStyle, getTransitionClass } from '@bendyline/squisq/doc';
@@ -8,7 +8,8 @@ export { a as CodeBlockCopyContext, M as MarkdownRenderer, b as MarkdownRenderer
8
8
  export { FenceRendererContext, MermaidDiagram, MermaidDiagramProps, useFenceRenderers } from './markdown/index.js';
9
9
  export { CanvasSection, CanvasSectionProps, ImageDisplayMode, LinearDocView, LinearDocViewProps, PageSectionView, PageSectionViewProps, PageViewContext, PageViewContextValue, usePageView } from './page/index.js';
10
10
  import * as react_jsx_runtime from 'react/jsx-runtime';
11
- export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TableLayer, TextLayer, TreeLayer, VideoLayer } from './layers/index.js';
11
+ export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TextLayer, TreeLayer, VideoLayer } from './layers/index.js';
12
+ export { T as TableLayer, a as TableLayerContentRenderer, b as TableLayerContentRendererProps } from './TableLayer-B7ADuUGc.js';
12
13
  export { MediaContext, MediaScheduleController, ModalDialogOptions, ResourcePolicyContext, UseDocPlaybackOptions, useAudioSync, useAutoSurface, useDocPlayback, useMediaProvider, useMediaSchedule, useMediaUrl, useModalDialog, useResourcePolicy, useViewportOrientation } from './hooks/index.js';
13
14
  export { FenceRenderContext, FenceRenderer, FenceRendererMap } from '@bendyline/squisq/fence';
14
15
  export { A as AudioActions, a as AudioController, b as AudioState } from './AudioController-DwMsPe38.js';
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  formatTime,
16
16
  resolveDocPlayerAppearance,
17
17
  useMediaClipDurations
18
- } from "./chunk-HK7TY64K.js";
18
+ } from "./chunk-KGWT454C.js";
19
19
  import {
20
20
  BlockRenderer,
21
21
  CanvasSection,
@@ -23,7 +23,7 @@ import {
23
23
  PageSectionView,
24
24
  PageViewContext,
25
25
  usePageView
26
- } from "./chunk-ZC7LI5UF.js";
26
+ } from "./chunk-5UGIE2QO.js";
27
27
  import {
28
28
  ImageLayer,
29
29
  MapLayer,
@@ -36,7 +36,7 @@ import {
36
36
  VideoLayer,
37
37
  getAnimationStyle,
38
38
  getTransitionClass
39
- } from "./chunk-4MP7CH3C.js";
39
+ } from "./chunk-XSOMFBH2.js";
40
40
  import {
41
41
  useModalDialog
42
42
  } from "./chunk-65POMKHR.js";
@@ -1,5 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { 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, Theme } from '@bendyline/squisq/schemas';
2
+ import { ImageLayer as ImageLayer$1, TextLayer as TextLayer$1, ShapeLayer as ShapeLayer$1, PathLayer as PathLayer$1, VideoLayer as VideoLayer$1, TreeLayer as TreeLayer$1, MapLayer as MapLayer$1, MermaidLayer as MermaidLayer$1, Theme } from '@bendyline/squisq/schemas';
3
+ export { T as TableLayer, a as TableLayerContentRenderer, b as TableLayerContentRendererProps } from '../TableLayer-B7ADuUGc.js';
4
+ import 'react';
3
5
 
4
6
  interface ImageLayerProps {
5
7
  layer: ImageLayer$1;
@@ -26,6 +28,8 @@ interface TextLayerProps {
26
28
  };
27
29
  /** Current time relative to block start */
28
30
  blockTime: number;
31
+ /** Shared scale selected once for every text layer on this slide. */
32
+ textScale?: number;
29
33
  }
30
34
  /**
31
35
  * Dispatch between the plain SVG-text renderer and the rich HTML renderer
@@ -75,18 +79,6 @@ interface VideoLayerProps {
75
79
  }
76
80
  declare function VideoLayer({ layer, basePath, viewport, blockTime, isPlaying, muted, }: VideoLayerProps): react_jsx_runtime.JSX.Element;
77
81
 
78
- interface TableLayerProps {
79
- layer: TableLayer$1;
80
- /** Viewport dimensions for percentage calculations */
81
- viewport: {
82
- width: number;
83
- height: number;
84
- };
85
- /** Current time relative to block start (for animation) */
86
- blockTime: number;
87
- }
88
- declare function TableLayer({ layer, viewport, blockTime }: TableLayerProps): react_jsx_runtime.JSX.Element;
89
-
90
82
  interface TreeLayerProps {
91
83
  layer: TreeLayer$1;
92
84
  viewport: {
@@ -123,4 +115,4 @@ interface MermaidLayerProps {
123
115
  /** Mermaid diagram hosted in HTML inside the slide SVG. */
124
116
  declare function MermaidLayer({ layer, viewport, blockTime, theme }: MermaidLayerProps): react_jsx_runtime.JSX.Element;
125
117
 
126
- export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TableLayer, TextLayer, TreeLayer, VideoLayer };
118
+ export { ImageLayer, MapLayer, MermaidLayer, PathLayer, ShapeLayer, TextLayer, TreeLayer, VideoLayer };
@@ -8,7 +8,7 @@ import {
8
8
  TextLayer,
9
9
  TreeLayer,
10
10
  VideoLayer
11
- } from "../chunk-4MP7CH3C.js";
11
+ } from "../chunk-XSOMFBH2.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-ZC7LI5UF.js";
8
- import "../chunk-4MP7CH3C.js";
7
+ } from "../chunk-5UGIE2QO.js";
8
+ import "../chunk-XSOMFBH2.js";
9
9
  import "../chunk-TT6ENR6T.js";
10
10
  import "../chunk-ZY5N3JPM.js";
11
11
  import "../chunk-WLUZTUNZ.js";
@@ -1,9 +1,10 @@
1
- export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, b as PipPosition, a as PipShape, P as PipSize, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, E as SlideNavActions, G as SocialCaptionOverlay, S as SquisqRenderAPI, V as VideoPresentation, H as formatTime } from '../player-DSMhm8SL.js';
1
+ export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, b as PipPosition, a as PipShape, P as PipSize, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, E as SlideNavActions, G as SocialCaptionOverlay, S as SquisqRenderAPI, V as VideoPresentation, H as formatTime } from '../player-BlD8zREs.js';
2
2
  export { a as CodeBlockCopyContext, C as CodeBlockCopyHandler } from '../MarkdownRenderer-CC9dOc6b.js';
3
3
  import 'react/jsx-runtime';
4
4
  import '@bendyline/squisq/schemas';
5
5
  import '@bendyline/squisq/doc';
6
6
  import '@bendyline/squisq/fence';
7
7
  import '../AudioController-DwMsPe38.js';
8
+ import '../TableLayer-B7ADuUGc.js';
8
9
  import 'react';
9
10
  import '@bendyline/squisq/markdown';
@@ -12,11 +12,11 @@ import {
12
12
  MediaClipLayer,
13
13
  SocialCaptionOverlay,
14
14
  formatTime
15
- } from "../chunk-HK7TY64K.js";
15
+ } from "../chunk-KGWT454C.js";
16
16
  import {
17
17
  BlockRenderer
18
- } from "../chunk-ZC7LI5UF.js";
19
- import "../chunk-4MP7CH3C.js";
18
+ } from "../chunk-5UGIE2QO.js";
19
+ import "../chunk-XSOMFBH2.js";
20
20
  import "../chunk-MVJQL2W2.js";
21
21
  import "../chunk-TT6ENR6T.js";
22
22
  import {
@@ -4,6 +4,7 @@ import { ViewportConfig, DashboardStyleId, CoverSlideTemplate, CoverSlidePlaybac
4
4
  import { FenceRendererMap } from '@bendyline/squisq/fence';
5
5
  import { a as AudioController } from './AudioController-DwMsPe38.js';
6
6
  import { C as CodeBlockCopyHandler } from './MarkdownRenderer-CC9dOc6b.js';
7
+ import { a as TableLayerContentRenderer } from './TableLayer-B7ADuUGc.js';
7
8
  import { CSSProperties } from 'react';
8
9
 
9
10
  /**
@@ -281,6 +282,8 @@ interface DocPlayerProps {
281
282
  * as SVG layers and do not consult it.
282
283
  */
283
284
  fenceRenderers?: FenceRendererMap;
285
+ /** Optional host renderer for interactive table-layer content. */
286
+ tableContentRenderer?: TableLayerContentRenderer;
284
287
  }
285
288
 
286
289
  /**
@@ -323,8 +326,12 @@ interface BlockRendererProps {
323
326
  animationsEnabled?: boolean;
324
327
  /** Resolved theme inherited by rich-media renderers such as Mermaid. */
325
328
  theme?: Theme;
329
+ /** Optional host renderer for interactive table content. */
330
+ tableContentRenderer?: TableLayerContentRenderer;
331
+ /** Grow all slide text by one shared factor without overflow or new overlap. */
332
+ growTextToFit?: boolean;
326
333
  }
327
- declare function BlockRenderer({ block, blockTime, basePath, isEntering, isExiting, transition, viewport, isPlaying, muted, animationsEnabled, theme, }: BlockRendererProps): react_jsx_runtime.JSX.Element;
334
+ declare function BlockRenderer({ block, blockTime, basePath, isEntering, isExiting, transition, viewport, isPlaying, muted, animationsEnabled, theme, tableContentRenderer, growTextToFit, }: BlockRendererProps): react_jsx_runtime.JSX.Element;
328
335
 
329
336
  interface CaptionOverlayProps {
330
337
  /** Caption track with timestamped phrases */