@bendyline/squisq 2.4.4 → 2.5.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/{Doc-BKKcPjfe.d.ts → Doc-DBadkoP4.d.ts} +30 -2
- package/dist/{ImageEditDoc-CU1cXxRd.d.ts → ImageEditDoc-Cq2a3c30.d.ts} +1 -1
- package/dist/{chunk-YQW6AQBV.js → chunk-6MVWWZHL.js} +1 -1
- package/dist/{chunk-GGTDYLW4.js → chunk-7Z5T3CUI.js} +1 -1
- package/dist/{chunk-OIIIHI3Y.js → chunk-GSJEGMKF.js} +273 -10
- package/dist/{chunk-CYRIVZTR.js → chunk-HXMV7WQB.js} +1 -1
- package/dist/{chunk-O3LLD7HG.js → chunk-NBKAXPSX.js} +1 -0
- package/dist/{chunk-GXUFHFYD.js → chunk-NNL3HHKA.js} +139 -15
- package/dist/doc/index.d.ts +116 -14
- package/dist/doc/index.js +18 -4
- package/dist/generate/index.d.ts +1 -1
- package/dist/imageEdit/index.d.ts +3 -3
- package/dist/index.d.ts +5 -5
- package/dist/index.js +20 -6
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/markdown/index.js +3 -3
- package/dist/{materializePageSection-WDJCTJEm.d.ts → materializePageSection-DgOFYge7.d.ts} +1 -1
- package/dist/narration/index.d.ts +1 -1
- package/dist/narration/index.js +3 -3
- package/dist/schemas/index.d.ts +4 -4
- package/dist/{themeLibrary-BMXXLZBU.d.ts → themeLibrary-8BQMY2HV.d.ts} +1 -1
- package/dist/transform/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -456,6 +456,25 @@ interface SectionHeaderInput extends BaseTemplateBlock {
|
|
|
456
456
|
/** Ambient motion for background image */
|
|
457
457
|
ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';
|
|
458
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* Big text - thumbnail-style display card with the title in gigantic
|
|
461
|
+
* uppercase type, sized to fill the frame minus a small padding margin.
|
|
462
|
+
* With an image, the title sits over a full-bleed photo with a theme-tinted
|
|
463
|
+
* contrast bloom behind the text; without one, it sits on a clean theme
|
|
464
|
+
* surface. Shows nothing but the title — body content feeds narration only.
|
|
465
|
+
* Built for YouTube covers and social thumbnails.
|
|
466
|
+
*/
|
|
467
|
+
interface BigTextInput extends BaseTemplateBlock {
|
|
468
|
+
template: 'bigText';
|
|
469
|
+
/** The display text (rendered uppercase). */
|
|
470
|
+
title: string;
|
|
471
|
+
/** Optional full-bleed background image path. */
|
|
472
|
+
imageSrc?: string;
|
|
473
|
+
/** Alt text for the background image. */
|
|
474
|
+
imageAlt?: string;
|
|
475
|
+
/** Ambient motion for the background image. */
|
|
476
|
+
ambientMotion?: 'zoomIn' | 'zoomOut' | 'panLeft' | 'panRight';
|
|
477
|
+
}
|
|
459
478
|
/**
|
|
460
479
|
* Content block - loss-averse heading and body layout.
|
|
461
480
|
*
|
|
@@ -1066,7 +1085,7 @@ type ChartTemplateInput = BarChartInput | ColumnChartInput | PieChartInput | Don
|
|
|
1066
1085
|
/**
|
|
1067
1086
|
* Union of all template block types.
|
|
1068
1087
|
*/
|
|
1069
|
-
type TemplateBlock = TitleBlockInput | SectionHeaderInput | ContentBlockInput | StatHighlightInput | QuoteBlockInput | FactCardInput | TwoColumnInput | DateEventInput | ImageWithCaptionInput | LeftFeatureInput | RightFeatureInput | MapBlockInput | FullBleedQuoteInput | ListBlockInput | PhotoGridInput | DefinitionCardInput | ComparisonBarInput | PullQuoteInput | VideoWithCaptionInput | VideoPullQuoteInput | DataTableInput | BarChartInput | ColumnChartInput | PieChartInput | DonutChartInput | LineChartInput | AreaChartInput | ScatterChartInput | DiagramBlockInput | TreeBlockInput | TimelineBlockInput | DrawingBlockInput | RawLayersInput;
|
|
1088
|
+
type TemplateBlock = TitleBlockInput | SectionHeaderInput | BigTextInput | ContentBlockInput | StatHighlightInput | QuoteBlockInput | FactCardInput | TwoColumnInput | DateEventInput | ImageWithCaptionInput | LeftFeatureInput | RightFeatureInput | MapBlockInput | FullBleedQuoteInput | ListBlockInput | PhotoGridInput | DefinitionCardInput | ComparisonBarInput | PullQuoteInput | VideoWithCaptionInput | VideoPullQuoteInput | DataTableInput | BarChartInput | ColumnChartInput | PieChartInput | DonutChartInput | LineChartInput | AreaChartInput | ScatterChartInput | DiagramBlockInput | TreeBlockInput | TimelineBlockInput | DrawingBlockInput | RawLayersInput;
|
|
1070
1089
|
/**
|
|
1071
1090
|
* A block can be either a raw Block or a TemplateBlock.
|
|
1072
1091
|
*/
|
|
@@ -2638,6 +2657,15 @@ interface TextStyle {
|
|
|
2638
2657
|
padding?: number;
|
|
2639
2658
|
/** Maximum number of lines before truncation (adds "..." to last line) */
|
|
2640
2659
|
maxLines?: number;
|
|
2660
|
+
/**
|
|
2661
|
+
* Fit the rendered text to the layer's box: the renderer measures the
|
|
2662
|
+
* real glyphs and scales the text down (never up) to stay inside the box,
|
|
2663
|
+
* and — when vertically centered — centers the whole wrapped block on the
|
|
2664
|
+
* anchor instead of hanging extra lines below it. For display type sized
|
|
2665
|
+
* from estimates (e.g. the bigText template), where the actual font can
|
|
2666
|
+
* run wider than any pure width model.
|
|
2667
|
+
*/
|
|
2668
|
+
shrinkToFit?: boolean;
|
|
2641
2669
|
}
|
|
2642
2670
|
/**
|
|
2643
2671
|
* Animation to apply to a layer.
|
|
@@ -2770,4 +2798,4 @@ declare function getBlockAtTime(blocks: Block[], time: number): Block | null;
|
|
|
2770
2798
|
*/
|
|
2771
2799
|
declare function getCaptionAtTime(captions: CaptionTrack | undefined, time: number): CaptionPhrase | null;
|
|
2772
2800
|
|
|
2773
|
-
export { type
|
|
2801
|
+
export { type ImageLayer as $, type AccentImage as A, type BarChartInput as B, type CaptionPhrase as C, DARK_SURFACE as D, DEFAULT_DOC_FONT as E, DEFAULT_TITLE_FONT as F, type DataTableInput as G, type DateEventInput as H, type DeepPartial as I, type DefinitionCardInput as J, type DiagramBlockInput as K, type DiagramEdgeAnchor as L, type DiagramTemplateEdge as M, type DiagramTemplateNode as N, type Doc as O, type DocBlock as P, type DocDiagnostic as Q, type DonutChartInput as R, type DrawingBlockInput as S, FRONTMATTER_CUSTOM_TEMPLATES_KEY as T, FRONTMATTER_CUSTOM_THEMES_KEY as U, type FactCardInput as V, type FontFamily as W, type FontFamilyKind as X, type FullBleedQuoteInput as Y, type GradientBackgroundConfig as Z, type ImageBackgroundConfig as _, type AccentPosition as a, type ScheduledClip as a$, type ImageTreatment as a0, type ImageWithCaptionInput as a1, LIGHT_SURFACE as a2, type Layer as a3, type LayerRepeat as a4, type LayoutHints as a5, type LeftFeatureInput as a6, type LineChartInput as a7, type LinearGradient as a8, type ListBlockInput as a9, type PageAccentRotation as aA, type PageBackground as aB, type PageDesignFamily as aC, type PageEmphasis as aD, type PageHeadingTreatment as aE, type PageSectionKind as aF, type PageSectionOverride as aG, type PageTokens as aH, type PathLayer as aI, type PatternBackgroundConfig as aJ, type PersistentLayer as aK, type PersistentLayerConfig as aL, type PersistentLayerTemplate as aM, type PersistentLayerTemplateConfig as aN, type PersistentLayerTemplateType as aO, type PhotoGridInput as aP, type PieChartInput as aQ, type PipStyle as aR, type Position as aS, type ProgressIndicatorConfig as aT, type PromotedBodyAnnotation as aU, type PullQuoteInput as aV, type QuoteBlockInput as aW, type RawLayersInput as aX, type RenderStyle as aY, type RightFeatureInput as aZ, type ScatterChartInput as a_, type MapBlockInput as aa, type MapLayer as ab, type MapMarker as ac, type MapTileStyle as ad, type MarkerStyle as ae, type MediaClip as af, type MediaScheduleOptions as ag, type MermaidLayer as ah, PAGE_ACCENT_STRATEGIES as ai, PAGE_BACKGROUNDS as aj, PAGE_BACKGROUND_RHYTHMS as ak, PAGE_DESIGN_FAMILIES as al, PAGE_DIVIDERS as am, PAGE_EMPHASES as an, PAGE_EYEBROWS as ao, PAGE_HEADING_CASES as ap, PAGE_HEADING_SCALES as aq, PAGE_HEADING_UNDERLINES as ar, PAGE_HERO_STYLES as as, PAGE_IMAGE_FRAMINGS as at, PAGE_NUMERAL_STYLES as au, PAGE_PATTERNS as av, PAGE_QUOTE_MARKS as aw, PAGE_SECTION_KINDS as ax, PAGE_SECTION_SPACINGS as ay, PAGE_SHADOWS as az, type AmbientGradientConfig as b, getSegmentAtTime as b$, type SectionHeaderInput as b0, type ShapeFilter as b1, type ShapeLayer as b2, type ShapePattern as b3, type SolidBackgroundConfig as b4, type StartBlockConfig as b5, type StatHighlightInput as b6, type SurfaceScheme as b7, THEME_SCHEMA_VERSION as b8, type TableLayer as b9, type TreeTemplateItem as bA, type TwoColumnInput as bB, VIEWPORT_PRESETS as bC, type VideoLayer as bD, type VideoPipPosition as bE, type VideoPipShape as bF, type VideoPipSize as bG, type VideoPlacement as bH, type VideoPresentation as bI, type VideoPullQuoteInput as bJ, type VideoWithCaptionInput as bK, type ViewportConfig as bL, type ViewportOrientation as bM, type ViewportPreset as bN, type VignetteConfig as bO, applySurface as bP, calculateDuration as bQ, calculateFontScale as bR, createTemplateContext as bS, createTheme as bT, createThemeRegistry as bU, getAspectRatioString as bV, getBlockAtTime as bW, getCaptionAtTime as bX, getDocPlaybackDuration as bY, getLayoutHints as bZ, getSafeTextBounds as b_, type TableLayerStyle as ba, type TemplateBlock as bb, type TemplateContext as bc, type TemplateFunction as bd, type TemplateRegistry as be, type TextLayer as bf, type TextStyle as bg, type Theme as bh, type ThemeColorPalette as bi, type ThemeColorScheme as bj, type ThemePageStyle as bk, type ThemeRegistry as bl, type ThemeSchemaVersion as bm, type ThemeSeedColors as bn, type ThemeStyle as bo, type ThemeTypography as bp, type TimelineBlockInput as bq, type TimelineTemplateEvent as br, type TimelineTemplateLink as bs, type TimelineTemplateTrack as bt, type TitleBlockInput as bu, type TitleCaptionConfig as bv, type TreeBlockInput as bw, type TreeLayer as bx, type TreeLayerItem as by, type TreeLayerStyle as bz, type Animation as c, getTwoColumnPositions as c0, getViewport as c1, getViewportOrientation as c2, isCustomTemplateDefinition as c3, isPersistentLayerTemplate as c4, isTemplateBlock as c5, scaledFontSize$1 as c6, resolveMediaSchedule as c7, scaledFontSize as c8, validateCustomTemplateDefinition as c9, type AnimationType as d, type AreaChartInput as e, type AudioBookmark as f, type AudioSegment as g, type AudioTimingData as h, type AudioTrack as i, type BigTextInput as j, type Block as k, type BlockConnection as l, type BorderStyle as m, type CaptionTrack as n, type CaptionWord as o, type ChartBaseFields as p, type ChartTemplateInput as q, type ColorScheme as r, type ColumnChartInput as s, type ComparisonBarInput as t, type ContentBlockInput as u, type CornerBrandingConfig as v, type CustomTemplateDefinition as w, type CustomTemplateLayer as x, type CustomTemplateValidationError as y, type CustomTemplateValidationResult as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as ImageLayer, bf as TextLayer, b2 as ShapeLayer, aI as PathLayer } from './Doc-DBadkoP4.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* ImageEditDoc — JSON document describing a layered, editable image.
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
sanitizeUrl,
|
|
57
57
|
splitKeyValueToken,
|
|
58
58
|
tokenizeAttrTokens
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-NBKAXPSX.js";
|
|
60
60
|
import {
|
|
61
61
|
extractPlainText,
|
|
62
62
|
readFrontmatterThemeId,
|
|
@@ -934,6 +934,138 @@ function sectionHeader(input, context) {
|
|
|
934
934
|
return layers;
|
|
935
935
|
}
|
|
936
936
|
|
|
937
|
+
// src/doc/templates/bigText.ts
|
|
938
|
+
var BIG_TEXT_LINE_HEIGHT = 1.05;
|
|
939
|
+
var BIG_TEXT_WIDTH_FRACTION = 0.92;
|
|
940
|
+
var BIG_TEXT_HEIGHT_FRACTION = 0.86;
|
|
941
|
+
var BIG_TEXT_CHAR_WIDTH = 0.62;
|
|
942
|
+
var BIG_TEXT_MIN_PX = 48;
|
|
943
|
+
function wrappedLineCount(wordLengths, charsPerLine) {
|
|
944
|
+
let lines = 1;
|
|
945
|
+
let current = 0;
|
|
946
|
+
for (const length of wordLengths) {
|
|
947
|
+
const withWord = current === 0 ? length : current + 1 + length;
|
|
948
|
+
if (withWord <= charsPerLine) {
|
|
949
|
+
current = withWord;
|
|
950
|
+
} else {
|
|
951
|
+
lines += 1;
|
|
952
|
+
current = length;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
return lines;
|
|
956
|
+
}
|
|
957
|
+
function fitBigTextSize(title, viewport) {
|
|
958
|
+
const availWidth = viewport.width * BIG_TEXT_WIDTH_FRACTION;
|
|
959
|
+
const availHeight = viewport.height * BIG_TEXT_HEIGHT_FRACTION;
|
|
960
|
+
const wordLengths = title.trim().split(/\s+/).filter(Boolean).map((word) => word.length);
|
|
961
|
+
if (wordLengths.length === 0) return Math.floor(availHeight / BIG_TEXT_LINE_HEIGHT);
|
|
962
|
+
const longestWord = Math.max(...wordLengths);
|
|
963
|
+
const widthCap = availWidth / (BIG_TEXT_CHAR_WIDTH * longestWord);
|
|
964
|
+
const singleLineCap = availHeight / BIG_TEXT_LINE_HEIGHT;
|
|
965
|
+
const fits = (size) => {
|
|
966
|
+
const charsPerLine = Math.max(1, Math.floor(availWidth / (size * BIG_TEXT_CHAR_WIDTH)));
|
|
967
|
+
const lines = wrappedLineCount(wordLengths, charsPerLine);
|
|
968
|
+
return lines * size * BIG_TEXT_LINE_HEIGHT <= availHeight;
|
|
969
|
+
};
|
|
970
|
+
let low = BIG_TEXT_MIN_PX;
|
|
971
|
+
let high = Math.min(widthCap, singleLineCap);
|
|
972
|
+
if (high <= low) return Math.max(BIG_TEXT_MIN_PX, Math.floor(high));
|
|
973
|
+
if (!fits(low)) return BIG_TEXT_MIN_PX;
|
|
974
|
+
for (let i = 0; i < 24; i += 1) {
|
|
975
|
+
const mid = (low + high) / 2;
|
|
976
|
+
if (fits(mid)) low = mid;
|
|
977
|
+
else high = mid;
|
|
978
|
+
}
|
|
979
|
+
return Math.floor(low);
|
|
980
|
+
}
|
|
981
|
+
function bigTextBloom(background) {
|
|
982
|
+
return `radial-gradient(ellipse at 50% 50%, ${withAlpha(background, 0.92)} 0%, ${withAlpha(background, 0.78)} 38%, ${withAlpha(background, 0.32)} 66%, ${withAlpha(background, 0)} 88%)`;
|
|
983
|
+
}
|
|
984
|
+
function bigText(input, context) {
|
|
985
|
+
const { title = "", imageSrc, imageAlt, ambientMotion } = input;
|
|
986
|
+
const { theme, viewport } = context;
|
|
987
|
+
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
988
|
+
const displayTitle = title.toUpperCase();
|
|
989
|
+
const titleFontSize = fitBigTextSize(displayTitle, viewport);
|
|
990
|
+
const layers = [];
|
|
991
|
+
if (imageSrc) {
|
|
992
|
+
layers.push(
|
|
993
|
+
{
|
|
994
|
+
type: "image",
|
|
995
|
+
id: "bigtext-image",
|
|
996
|
+
content: {
|
|
997
|
+
src: imageSrc,
|
|
998
|
+
alt: imageAlt || title,
|
|
999
|
+
fit: "cover",
|
|
1000
|
+
...treatment ? { treatment } : {}
|
|
1001
|
+
},
|
|
1002
|
+
position: { x: 0, y: 0, width: "100%", height: "100%" },
|
|
1003
|
+
animation: mapAmbientMotion(ambientMotion, 8) ?? {
|
|
1004
|
+
type: "slowZoom",
|
|
1005
|
+
duration: 8,
|
|
1006
|
+
direction: "in"
|
|
1007
|
+
}
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
type: "shape",
|
|
1011
|
+
id: "bigtext-bloom",
|
|
1012
|
+
content: {
|
|
1013
|
+
shape: "rect",
|
|
1014
|
+
fill: bigTextBloom(theme.colors.background)
|
|
1015
|
+
},
|
|
1016
|
+
position: { x: 0, y: 0, width: "100%", height: "100%" }
|
|
1017
|
+
}
|
|
1018
|
+
);
|
|
1019
|
+
} else {
|
|
1020
|
+
layers.push(
|
|
1021
|
+
{
|
|
1022
|
+
type: "shape",
|
|
1023
|
+
id: "bigtext-bg",
|
|
1024
|
+
content: {
|
|
1025
|
+
shape: "rect",
|
|
1026
|
+
fill: theme.colors.background
|
|
1027
|
+
},
|
|
1028
|
+
position: { x: 0, y: 0, width: "100%", height: "100%" }
|
|
1029
|
+
},
|
|
1030
|
+
{
|
|
1031
|
+
type: "shape",
|
|
1032
|
+
id: "bigtext-tint",
|
|
1033
|
+
content: {
|
|
1034
|
+
shape: "rect",
|
|
1035
|
+
fill: `radial-gradient(ellipse at 50% 50%, ${withAlpha(theme.colors.primary, 0.38)} 0%, ${withAlpha(theme.colors.primary, 0.14)} 48%, ${withAlpha(theme.colors.primary, 0)} 78%)`
|
|
1036
|
+
},
|
|
1037
|
+
position: { x: 0, y: 0, width: "100%", height: "100%" }
|
|
1038
|
+
}
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
layers.push({
|
|
1042
|
+
type: "text",
|
|
1043
|
+
id: "bigtext-title",
|
|
1044
|
+
content: {
|
|
1045
|
+
text: displayTitle,
|
|
1046
|
+
style: {
|
|
1047
|
+
fontSize: titleFontSize,
|
|
1048
|
+
fontFamily: getThemeFont(context, "title"),
|
|
1049
|
+
fontWeight: "bold",
|
|
1050
|
+
color: theme.colors.text,
|
|
1051
|
+
textAlign: "center",
|
|
1052
|
+
lineHeight: BIG_TEXT_LINE_HEIGHT,
|
|
1053
|
+
shadow: !!imageSrc,
|
|
1054
|
+
shrinkToFit: true
|
|
1055
|
+
}
|
|
1056
|
+
},
|
|
1057
|
+
position: {
|
|
1058
|
+
x: "50%",
|
|
1059
|
+
y: "50%",
|
|
1060
|
+
anchor: "center",
|
|
1061
|
+
width: `${BIG_TEXT_WIDTH_FRACTION * 100}%`,
|
|
1062
|
+
height: `${BIG_TEXT_HEIGHT_FRACTION * 100}%`
|
|
1063
|
+
},
|
|
1064
|
+
animation: themedEntrance(context, "text", { type: "fadeIn", duration: 1 })
|
|
1065
|
+
});
|
|
1066
|
+
return layers;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
937
1069
|
// src/doc/templates/contentBlock.ts
|
|
938
1070
|
function completeBodyText(context) {
|
|
939
1071
|
return (context.block?.contents ?? []).filter((node) => !(node.type === "code" && node.lang?.trim().toLowerCase() === "mermaid")).map((node) => extractPlainText(node)).join("\n").trim();
|
|
@@ -2763,6 +2895,13 @@ function deriveTemplateInputs(templateName, headingText, contents, options = {})
|
|
|
2763
2895
|
if (!img) return placeholders ? { caption: headingText } : null;
|
|
2764
2896
|
return { imageSrc: img.src, imageAlt: img.alt || headingText, caption: headingText };
|
|
2765
2897
|
}
|
|
2898
|
+
case "bigText": {
|
|
2899
|
+
const img = extractFirstImage(contents);
|
|
2900
|
+
return {
|
|
2901
|
+
title: headingText,
|
|
2902
|
+
...img ? { imageSrc: img.src, imageAlt: img.alt || headingText } : {}
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2766
2905
|
case "photoGrid": {
|
|
2767
2906
|
const images = extractImages(contents, 4);
|
|
2768
2907
|
if (images.length < 2) return placeholders ? {} : null;
|
|
@@ -3773,9 +3912,9 @@ function fitDiagramLabel(text, boxWidth, boxHeight, preferredFontSize) {
|
|
|
3773
3912
|
};
|
|
3774
3913
|
}
|
|
3775
3914
|
function countWrappedLines(text, fontSize, maxWidth) {
|
|
3776
|
-
return text.split("\n").reduce((count, line) => count +
|
|
3915
|
+
return text.split("\n").reduce((count, line) => count + wrappedLineCount2(line, fontSize, maxWidth), 0);
|
|
3777
3916
|
}
|
|
3778
|
-
function
|
|
3917
|
+
function wrappedLineCount2(text, fontSize, maxWidth) {
|
|
3779
3918
|
if (!text.trim()) return 1;
|
|
3780
3919
|
const charsPerLine = Math.floor(maxWidth / (fontSize * 0.5));
|
|
3781
3920
|
if (charsPerLine <= 0) return 1;
|
|
@@ -6621,6 +6760,7 @@ function scatterChart(input, context) {
|
|
|
6621
6760
|
var templateRegistry = {
|
|
6622
6761
|
title: titleBlock,
|
|
6623
6762
|
sectionHeader,
|
|
6763
|
+
bigText,
|
|
6624
6764
|
content: contentBlock,
|
|
6625
6765
|
statHighlight,
|
|
6626
6766
|
quote: quoteBlock,
|
|
@@ -6835,6 +6975,12 @@ var TEMPLATE_INPUT_DESCRIPTORS = {
|
|
|
6835
6975
|
{ key: "imageAlt", description: "Alt text for the background image" },
|
|
6836
6976
|
{ key: "ambientMotion", description: "Slow zoom/pan effect", values: AMBIENT_MOTION_VALUES }
|
|
6837
6977
|
],
|
|
6978
|
+
bigText: [
|
|
6979
|
+
{ key: "title", description: "The display text (rendered uppercase)" },
|
|
6980
|
+
{ key: "imageSrc", description: "Optional full-bleed background image path" },
|
|
6981
|
+
{ key: "imageAlt", description: "Alt text for the background image" },
|
|
6982
|
+
{ key: "ambientMotion", description: "Slow zoom/pan effect", values: AMBIENT_MOTION_VALUES }
|
|
6983
|
+
],
|
|
6838
6984
|
content: [{ key: "title", description: "Heading shown above the complete body" }],
|
|
6839
6985
|
statHighlight: [
|
|
6840
6986
|
{ key: "stat", description: 'The statistic (e.g. "89%", "2x")' },
|
|
@@ -7251,6 +7397,15 @@ var BLOCK_MEDIA_LAYOUT_POLICIES = {
|
|
|
7251
7397
|
unconsumedMedia: "reserve-when-no-native-media",
|
|
7252
7398
|
variants: TITLE_VARIANTS
|
|
7253
7399
|
},
|
|
7400
|
+
bigText: {
|
|
7401
|
+
summary: "Uses its authored background image (behind a contrast bloom) when present; otherwise renders gigantic text on the theme surface.",
|
|
7402
|
+
noMedia: "template-without-optional-media",
|
|
7403
|
+
ownership: "optional-native",
|
|
7404
|
+
nativeLayout: "background-image",
|
|
7405
|
+
additionalMediaLayout: "overlay-inset",
|
|
7406
|
+
unconsumedMedia: "reserve-when-no-native-media",
|
|
7407
|
+
variants: TITLE_VARIANTS
|
|
7408
|
+
},
|
|
7254
7409
|
content: {
|
|
7255
7410
|
summary: "Preserves the complete heading and body; supplemental media receives a companion field.",
|
|
7256
7411
|
noMedia: "template-default",
|
|
@@ -8392,6 +8547,10 @@ var TEMPLATE_METADATA = {
|
|
|
8392
8547
|
label: "Section Header",
|
|
8393
8548
|
description: "A clean section break with a prominent title and optional background image."
|
|
8394
8549
|
},
|
|
8550
|
+
bigText: {
|
|
8551
|
+
label: "Big Text",
|
|
8552
|
+
description: "Gigantic uppercase display text \u2014 thumbnail-style \u2014 on a theme surface or over an image with a contrast bloom."
|
|
8553
|
+
},
|
|
8395
8554
|
content: {
|
|
8396
8555
|
label: "Content",
|
|
8397
8556
|
description: "Shows a heading and the complete body in a loss-averse content-first layout."
|
|
@@ -8532,6 +8691,12 @@ var TEMPLATE_AUTHORING_METADATA = {
|
|
|
8532
8691
|
safeForContentFirst: false,
|
|
8533
8692
|
placement: "heading"
|
|
8534
8693
|
},
|
|
8694
|
+
bigText: {
|
|
8695
|
+
role: "opener",
|
|
8696
|
+
bodyPolicy: "ignored",
|
|
8697
|
+
safeForContentFirst: false,
|
|
8698
|
+
placement: "heading"
|
|
8699
|
+
},
|
|
8535
8700
|
content: {
|
|
8536
8701
|
role: "content",
|
|
8537
8702
|
bodyPolicy: "complete",
|
|
@@ -8883,8 +9048,81 @@ function startBlockToCoverInput(config) {
|
|
|
8883
9048
|
heroLicense: config.heroLicense
|
|
8884
9049
|
};
|
|
8885
9050
|
}
|
|
8886
|
-
function expandCoverBlock(config, context) {
|
|
9051
|
+
function expandCoverBlock(config, context, template = "cover") {
|
|
8887
9052
|
const input = startBlockToCoverInput(config);
|
|
9053
|
+
const base = {
|
|
9054
|
+
id: "cover-block",
|
|
9055
|
+
duration: 0,
|
|
9056
|
+
audioSegment: -1
|
|
9057
|
+
};
|
|
9058
|
+
if (template === "title") {
|
|
9059
|
+
return titleBlock(
|
|
9060
|
+
{
|
|
9061
|
+
...base,
|
|
9062
|
+
template: "title",
|
|
9063
|
+
title: input.title,
|
|
9064
|
+
subtitle: input.subtitle
|
|
9065
|
+
},
|
|
9066
|
+
context
|
|
9067
|
+
);
|
|
9068
|
+
}
|
|
9069
|
+
if (template === "sectionHeader") {
|
|
9070
|
+
return sectionHeader(
|
|
9071
|
+
{
|
|
9072
|
+
...base,
|
|
9073
|
+
template: "sectionHeader",
|
|
9074
|
+
title: input.title,
|
|
9075
|
+
imageSrc: input.heroSrc,
|
|
9076
|
+
imageAlt: input.heroAlt,
|
|
9077
|
+
ambientMotion: input.ambientMotion
|
|
9078
|
+
},
|
|
9079
|
+
context
|
|
9080
|
+
);
|
|
9081
|
+
}
|
|
9082
|
+
if (template === "bigText" || template === "bigTextImage") {
|
|
9083
|
+
const useHero = template === "bigTextImage" && !!input.heroSrc;
|
|
9084
|
+
return bigText(
|
|
9085
|
+
{
|
|
9086
|
+
...base,
|
|
9087
|
+
template: "bigText",
|
|
9088
|
+
title: input.title,
|
|
9089
|
+
...useHero ? {
|
|
9090
|
+
imageSrc: input.heroSrc,
|
|
9091
|
+
imageAlt: input.heroAlt ?? input.title,
|
|
9092
|
+
ambientMotion: input.ambientMotion
|
|
9093
|
+
} : {}
|
|
9094
|
+
},
|
|
9095
|
+
context
|
|
9096
|
+
);
|
|
9097
|
+
}
|
|
9098
|
+
if (template === "imageWithCaption") {
|
|
9099
|
+
if (!input.heroSrc) {
|
|
9100
|
+
return titleBlock(
|
|
9101
|
+
{
|
|
9102
|
+
...base,
|
|
9103
|
+
template: "title",
|
|
9104
|
+
title: input.title,
|
|
9105
|
+
subtitle: input.subtitle
|
|
9106
|
+
},
|
|
9107
|
+
context
|
|
9108
|
+
);
|
|
9109
|
+
}
|
|
9110
|
+
return imageWithCaption(
|
|
9111
|
+
{
|
|
9112
|
+
...base,
|
|
9113
|
+
template: "imageWithCaption",
|
|
9114
|
+
imageSrc: input.heroSrc,
|
|
9115
|
+
imageAlt: input.heroAlt ?? input.title,
|
|
9116
|
+
caption: input.title,
|
|
9117
|
+
subtitle: input.subtitle,
|
|
9118
|
+
ambientMotion: input.ambientMotion,
|
|
9119
|
+
imageCredit: input.heroCredit,
|
|
9120
|
+
imageLicense: input.heroLicense,
|
|
9121
|
+
isTitle: true
|
|
9122
|
+
},
|
|
9123
|
+
context
|
|
9124
|
+
);
|
|
9125
|
+
}
|
|
8888
9126
|
return coverBlock(input, context);
|
|
8889
9127
|
}
|
|
8890
9128
|
|
|
@@ -10141,7 +10379,7 @@ function markdownToDoc(markdownDoc, options) {
|
|
|
10141
10379
|
...documentMedia.length > 0 ? { documentMedia } : {}
|
|
10142
10380
|
};
|
|
10143
10381
|
if (options?.generateCoverBlock ?? true) {
|
|
10144
|
-
const coverConfig = buildStartBlock(markdownDoc, rootBlocks);
|
|
10382
|
+
const coverConfig = buildStartBlock(markdownDoc, rootBlocks, options?.fileName);
|
|
10145
10383
|
if (coverConfig) {
|
|
10146
10384
|
doc.startBlock = coverConfig;
|
|
10147
10385
|
}
|
|
@@ -10391,12 +10629,35 @@ function findFirstImage(node) {
|
|
|
10391
10629
|
}
|
|
10392
10630
|
return void 0;
|
|
10393
10631
|
}
|
|
10394
|
-
function
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10632
|
+
function shallowestHeadingBlock(rootBlocks) {
|
|
10633
|
+
let best;
|
|
10634
|
+
for (const block of rootBlocks) {
|
|
10635
|
+
const depth = block.sourceHeading?.depth;
|
|
10636
|
+
if (depth === void 0) continue;
|
|
10637
|
+
const title = block.title ?? extractPlainText(block.sourceHeading);
|
|
10638
|
+
if (!title) continue;
|
|
10639
|
+
if (!best || depth < best.sourceHeading.depth) {
|
|
10640
|
+
best = block;
|
|
10641
|
+
if (depth === 1) break;
|
|
10642
|
+
}
|
|
10643
|
+
}
|
|
10644
|
+
return best;
|
|
10645
|
+
}
|
|
10646
|
+
function fileNameCoverTitle(fileName) {
|
|
10647
|
+
if (!fileName) return void 0;
|
|
10648
|
+
const base = fileName.split(/[\\/]/).pop() ?? "";
|
|
10649
|
+
const stem = base.replace(/\.[^.]+$/, "").replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim();
|
|
10650
|
+
if (!stem) return void 0;
|
|
10651
|
+
return stem.charAt(0).toUpperCase() + stem.slice(1);
|
|
10652
|
+
}
|
|
10653
|
+
function buildStartBlock(markdownDoc, rootBlocks, fileName) {
|
|
10654
|
+
const frontmatterTitle = typeof markdownDoc.frontmatter?.title === "string" ? markdownDoc.frontmatter.title.trim() : void 0;
|
|
10655
|
+
const headingBlock = shallowestHeadingBlock(rootBlocks);
|
|
10656
|
+
const headingTitle = headingBlock ? headingBlock.title ?? extractPlainText(headingBlock.sourceHeading) : void 0;
|
|
10657
|
+
const title = frontmatterTitle || headingTitle || fileNameCoverTitle(fileName);
|
|
10398
10658
|
if (!title) return void 0;
|
|
10399
|
-
const
|
|
10659
|
+
const subtitleBlock = headingBlock ?? rootBlocks[0];
|
|
10660
|
+
const subtitle = subtitleBlock?.contents?.[0]?.type === "paragraph" ? extractPlainText(subtitleBlock.contents[0]) : void 0;
|
|
10400
10661
|
const firstImage = findFirstImage(markdownDoc);
|
|
10401
10662
|
const config = {
|
|
10402
10663
|
title,
|
|
@@ -10744,6 +11005,8 @@ export {
|
|
|
10744
11005
|
createAccentLayers,
|
|
10745
11006
|
adjustY,
|
|
10746
11007
|
sectionHeader,
|
|
11008
|
+
fitBigTextSize,
|
|
11009
|
+
bigText,
|
|
10747
11010
|
contentBlock,
|
|
10748
11011
|
statHighlight,
|
|
10749
11012
|
quoteBlock,
|