@qkix/better-blocks-react-renderer 0.18.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/LICENSE +21 -0
- package/README.md +970 -0
- package/dist/index.d.mts +189 -0
- package/dist/index.d.ts +189 -0
- package/dist/index.js +1288 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1269 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +105 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1269 @@
|
|
|
1
|
+
// src/BlocksRenderer.tsx
|
|
2
|
+
import {
|
|
3
|
+
Fragment,
|
|
4
|
+
cloneElement,
|
|
5
|
+
createElement,
|
|
6
|
+
isValidElement
|
|
7
|
+
} from "react";
|
|
8
|
+
import katex from "katex";
|
|
9
|
+
import {
|
|
10
|
+
buildTextMarks,
|
|
11
|
+
formatFileSize,
|
|
12
|
+
getBlockStyle as coreGetBlockStyle,
|
|
13
|
+
getDefaultMarkRender,
|
|
14
|
+
getFileIcon,
|
|
15
|
+
getListStyleType,
|
|
16
|
+
getModifierProps,
|
|
17
|
+
getPlainText
|
|
18
|
+
} from "@qkix/better-blocks-core";
|
|
19
|
+
|
|
20
|
+
// src/media.ts
|
|
21
|
+
import { getAspectRatio } from "@qkix/better-blocks-core";
|
|
22
|
+
var MEDIA_ALIGN_ITEMS = {
|
|
23
|
+
left: "flex-start",
|
|
24
|
+
center: "center",
|
|
25
|
+
right: "flex-end",
|
|
26
|
+
none: "stretch"
|
|
27
|
+
};
|
|
28
|
+
var MEDIA_MAX_WIDTH = "48rem";
|
|
29
|
+
function getMediaFigureStyle(alignment) {
|
|
30
|
+
return {
|
|
31
|
+
display: "flex",
|
|
32
|
+
flexDirection: "column",
|
|
33
|
+
gap: "0.5rem",
|
|
34
|
+
margin: "1rem 0",
|
|
35
|
+
alignItems: MEDIA_ALIGN_ITEMS[alignment]
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function getMediaFrameStyle(alignment, aspectRatio) {
|
|
39
|
+
return {
|
|
40
|
+
width: "100%",
|
|
41
|
+
maxWidth: alignment === "none" ? "100%" : MEDIA_MAX_WIDTH,
|
|
42
|
+
aspectRatio
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
var MEDIA_CAPTION_STYLE = {
|
|
46
|
+
fontSize: "0.875rem",
|
|
47
|
+
color: "#6b7280"
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/CodeBlock.tsx
|
|
51
|
+
import { useEffect, useRef, useState } from "react";
|
|
52
|
+
|
|
53
|
+
// src/code.ts
|
|
54
|
+
import { normalizeCodeLang } from "@qkix/better-blocks-core";
|
|
55
|
+
|
|
56
|
+
// src/CodeBlock.tsx
|
|
57
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
58
|
+
var highlighters = /* @__PURE__ */ new Map();
|
|
59
|
+
function loadHighlighter(theme, lang) {
|
|
60
|
+
let highlighter = highlighters.get(theme);
|
|
61
|
+
if (!highlighter) {
|
|
62
|
+
highlighter = import("shiki").then(
|
|
63
|
+
(shiki) => shiki.createHighlighter({ themes: [theme], langs: [lang] })
|
|
64
|
+
);
|
|
65
|
+
highlighters.set(theme, highlighter);
|
|
66
|
+
return highlighter;
|
|
67
|
+
}
|
|
68
|
+
return highlighter.then(async (instance) => {
|
|
69
|
+
if (!instance.getLoadedLanguages().includes(lang)) {
|
|
70
|
+
await instance.loadLanguage(lang);
|
|
71
|
+
}
|
|
72
|
+
return instance;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function CopyButton({ plainText }) {
|
|
76
|
+
const [copied, setCopied] = useState(false);
|
|
77
|
+
const timer = useRef(null);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
return () => {
|
|
80
|
+
if (timer.current) clearTimeout(timer.current);
|
|
81
|
+
};
|
|
82
|
+
}, []);
|
|
83
|
+
const handleCopy = () => {
|
|
84
|
+
if (!navigator.clipboard) return;
|
|
85
|
+
navigator.clipboard.writeText(plainText).then(() => {
|
|
86
|
+
setCopied(true);
|
|
87
|
+
if (timer.current) clearTimeout(timer.current);
|
|
88
|
+
timer.current = setTimeout(() => setCopied(false), 2e3);
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
return /* @__PURE__ */ jsx("button", { className: "bb-code-copy", type: "button", onClick: handleCopy, "aria-label": "Copy code", children: copied ? "Copied!" : "Copy" });
|
|
92
|
+
}
|
|
93
|
+
function CodeBlock({
|
|
94
|
+
plainText,
|
|
95
|
+
language,
|
|
96
|
+
theme,
|
|
97
|
+
copyButton
|
|
98
|
+
}) {
|
|
99
|
+
const [html, setHtml] = useState(null);
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
let cancelled = false;
|
|
102
|
+
setHtml(null);
|
|
103
|
+
if (!plainText) return;
|
|
104
|
+
const lang = normalizeCodeLang(language);
|
|
105
|
+
loadHighlighter(theme, lang).then((highlighter) => highlighter.codeToHtml(plainText, { lang, theme })).then((highlighted) => {
|
|
106
|
+
if (!cancelled) setHtml(highlighted);
|
|
107
|
+
}).catch(() => {
|
|
108
|
+
if (!cancelled) setHtml(null);
|
|
109
|
+
});
|
|
110
|
+
return () => {
|
|
111
|
+
cancelled = true;
|
|
112
|
+
};
|
|
113
|
+
}, [plainText, language, theme]);
|
|
114
|
+
return /* @__PURE__ */ jsxs("div", { className: "bb-code", children: [
|
|
115
|
+
html ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsx("pre", { className: "bb-code-pre", children: /* @__PURE__ */ jsx("code", { children: plainText }) }),
|
|
116
|
+
copyButton && /* @__PURE__ */ jsx(CopyButton, { plainText })
|
|
117
|
+
] });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/MermaidDiagram.tsx
|
|
121
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
122
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
123
|
+
var mermaidPromise = null;
|
|
124
|
+
function loadMermaid() {
|
|
125
|
+
if (!mermaidPromise) {
|
|
126
|
+
mermaidPromise = import("mermaid").then((mod) => {
|
|
127
|
+
const mermaid = mod.default;
|
|
128
|
+
mermaid.initialize({ startOnLoad: false });
|
|
129
|
+
return mermaid;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return mermaidPromise;
|
|
133
|
+
}
|
|
134
|
+
var renderCount = 0;
|
|
135
|
+
function MermaidDiagram({ value }) {
|
|
136
|
+
const [svg, setSvg] = useState2(null);
|
|
137
|
+
useEffect2(() => {
|
|
138
|
+
let cancelled = false;
|
|
139
|
+
setSvg(null);
|
|
140
|
+
if (!value) return;
|
|
141
|
+
loadMermaid().then((mermaid) => mermaid.render(`bb-mermaid-${renderCount++}`, value)).then(({ svg: svg2 }) => {
|
|
142
|
+
if (!cancelled) setSvg(svg2);
|
|
143
|
+
}).catch(() => {
|
|
144
|
+
if (!cancelled) setSvg(null);
|
|
145
|
+
});
|
|
146
|
+
return () => {
|
|
147
|
+
cancelled = true;
|
|
148
|
+
};
|
|
149
|
+
}, [value]);
|
|
150
|
+
if (svg) {
|
|
151
|
+
return /* @__PURE__ */ jsx2("div", { className: "mermaid-diagram", dangerouslySetInnerHTML: { __html: svg } });
|
|
152
|
+
}
|
|
153
|
+
return /* @__PURE__ */ jsx2("pre", { className: "mermaid-source", children: value });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/SocialEmbed.tsx
|
|
157
|
+
import { useEffect as useEffect3, useMemo, useRef as useRef2 } from "react";
|
|
158
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
159
|
+
var socialWindow = () => window;
|
|
160
|
+
var WIDGET_SCRIPTS = {
|
|
161
|
+
twitter: {
|
|
162
|
+
src: "https://platform.twitter.com/widgets.js",
|
|
163
|
+
process: () => {
|
|
164
|
+
var _a, _b;
|
|
165
|
+
const load = (_b = (_a = socialWindow().twttr) == null ? void 0 : _a.widgets) == null ? void 0 : _b.load;
|
|
166
|
+
load == null ? void 0 : load();
|
|
167
|
+
return Boolean(load);
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
instagram: {
|
|
171
|
+
src: "https://www.instagram.com/embed.js",
|
|
172
|
+
process: () => {
|
|
173
|
+
var _a, _b;
|
|
174
|
+
const process = (_b = (_a = socialWindow().instgrm) == null ? void 0 : _a.Embeds) == null ? void 0 : _b.process;
|
|
175
|
+
process == null ? void 0 : process();
|
|
176
|
+
return Boolean(process);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
tiktok: {
|
|
180
|
+
src: "https://www.tiktok.com/embed.js",
|
|
181
|
+
process: (container) => {
|
|
182
|
+
var _a, _b;
|
|
183
|
+
const render = (_b = (_a = socialWindow().tiktokEmbed) == null ? void 0 : _a.lib) == null ? void 0 : _b.render;
|
|
184
|
+
render == null ? void 0 : render(Array.from(container.querySelectorAll(".tiktok-embed")));
|
|
185
|
+
return Boolean(render);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
pinterest: {
|
|
189
|
+
src: "https://assets.pinterest.com/js/pinit.js",
|
|
190
|
+
process: () => {
|
|
191
|
+
var _a;
|
|
192
|
+
const build = (_a = socialWindow().PinUtils) == null ? void 0 : _a.build;
|
|
193
|
+
build == null ? void 0 : build();
|
|
194
|
+
return Boolean(build);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
facebook: {
|
|
198
|
+
src: "https://connect.facebook.net/en_US/sdk.js",
|
|
199
|
+
process: () => {
|
|
200
|
+
var _a, _b;
|
|
201
|
+
const parse = (_b = (_a = socialWindow().FB) == null ? void 0 : _a.XFBML) == null ? void 0 : _b.parse;
|
|
202
|
+
parse == null ? void 0 : parse();
|
|
203
|
+
return Boolean(parse);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
linkedin: null
|
|
207
|
+
};
|
|
208
|
+
var PLATFORM_LABELS = {
|
|
209
|
+
twitter: "X",
|
|
210
|
+
instagram: "Instagram",
|
|
211
|
+
facebook: "Facebook",
|
|
212
|
+
tiktok: "TikTok",
|
|
213
|
+
linkedin: "LinkedIn",
|
|
214
|
+
pinterest: "Pinterest"
|
|
215
|
+
};
|
|
216
|
+
var SCRIPT_MARKER = "data-bb-social-script";
|
|
217
|
+
var scriptPromises = /* @__PURE__ */ new Map();
|
|
218
|
+
var reinjected = /* @__PURE__ */ new Set();
|
|
219
|
+
function injectScript(src, platform) {
|
|
220
|
+
const promise = new Promise((resolve) => {
|
|
221
|
+
const script = document.createElement("script");
|
|
222
|
+
script.src = src;
|
|
223
|
+
script.async = true;
|
|
224
|
+
script.setAttribute(SCRIPT_MARKER, platform);
|
|
225
|
+
script.addEventListener("load", () => resolve());
|
|
226
|
+
script.addEventListener("error", () => resolve());
|
|
227
|
+
document.body.appendChild(script);
|
|
228
|
+
});
|
|
229
|
+
scriptPromises.set(src, promise);
|
|
230
|
+
return promise;
|
|
231
|
+
}
|
|
232
|
+
function loadWidgetScript(src, platform) {
|
|
233
|
+
if (typeof document === "undefined") return Promise.resolve();
|
|
234
|
+
const cached = scriptPromises.get(src);
|
|
235
|
+
if (cached) return cached;
|
|
236
|
+
const existing = document.querySelector(`script[${SCRIPT_MARKER}="${platform}"]`);
|
|
237
|
+
if (existing) {
|
|
238
|
+
const resolved = Promise.resolve();
|
|
239
|
+
scriptPromises.set(src, resolved);
|
|
240
|
+
return resolved;
|
|
241
|
+
}
|
|
242
|
+
return injectScript(src, platform);
|
|
243
|
+
}
|
|
244
|
+
function reinjectWidgetScript(src, platform) {
|
|
245
|
+
if (typeof document === "undefined" || reinjected.has(platform)) return;
|
|
246
|
+
reinjected.add(platform);
|
|
247
|
+
document.querySelectorAll(`script[${SCRIPT_MARKER}="${platform}"]`).forEach((script) => {
|
|
248
|
+
script.remove();
|
|
249
|
+
});
|
|
250
|
+
scriptPromises.delete(src);
|
|
251
|
+
void injectScript(src, platform);
|
|
252
|
+
}
|
|
253
|
+
var SCRIPT_TAG = /<script\b[^>]*>[\s\S]*?<\/script\s*>/gi;
|
|
254
|
+
function stripScripts(html) {
|
|
255
|
+
return html == null ? void 0 : html.replace(SCRIPT_TAG, "");
|
|
256
|
+
}
|
|
257
|
+
function FallbackCard({
|
|
258
|
+
url,
|
|
259
|
+
oembed,
|
|
260
|
+
providerName
|
|
261
|
+
}) {
|
|
262
|
+
var _a;
|
|
263
|
+
const title = (_a = oembed == null ? void 0 : oembed.title) != null ? _a : (oembed == null ? void 0 : oembed.author) ? `Post by ${oembed.author}` : null;
|
|
264
|
+
const style = {
|
|
265
|
+
display: "inline-flex",
|
|
266
|
+
alignItems: "center",
|
|
267
|
+
gap: "0.75rem",
|
|
268
|
+
padding: "0.75rem 1rem",
|
|
269
|
+
border: "1px solid #d0d7de",
|
|
270
|
+
borderRadius: "0.5rem",
|
|
271
|
+
textDecoration: "none",
|
|
272
|
+
color: "inherit",
|
|
273
|
+
textAlign: "left"
|
|
274
|
+
};
|
|
275
|
+
const Tag = url ? "a" : "div";
|
|
276
|
+
const linkProps = url ? { href: url, target: "_blank", rel: "noopener noreferrer" } : {};
|
|
277
|
+
return /* @__PURE__ */ jsxs2(Tag, { className: "bb-social-embed-fallback", style, ...linkProps, children: [
|
|
278
|
+
(oembed == null ? void 0 : oembed.thumbnailUrl) && /* @__PURE__ */ jsx3(
|
|
279
|
+
"img",
|
|
280
|
+
{
|
|
281
|
+
className: "bb-social-embed-fallback-thumb",
|
|
282
|
+
src: oembed.thumbnailUrl,
|
|
283
|
+
alt: "",
|
|
284
|
+
loading: "lazy",
|
|
285
|
+
width: 48,
|
|
286
|
+
height: 48,
|
|
287
|
+
style: { borderRadius: "0.25rem", objectFit: "cover", flexShrink: 0 }
|
|
288
|
+
}
|
|
289
|
+
),
|
|
290
|
+
/* @__PURE__ */ jsxs2("span", { className: "bb-social-embed-fallback-body", children: [
|
|
291
|
+
/* @__PURE__ */ jsx3(
|
|
292
|
+
"span",
|
|
293
|
+
{
|
|
294
|
+
className: "bb-social-embed-fallback-title",
|
|
295
|
+
style: { display: "block", fontWeight: 600 },
|
|
296
|
+
children: title != null ? title : `View on ${providerName}`
|
|
297
|
+
}
|
|
298
|
+
),
|
|
299
|
+
title && /* @__PURE__ */ jsx3(
|
|
300
|
+
"span",
|
|
301
|
+
{
|
|
302
|
+
className: "bb-social-embed-fallback-provider",
|
|
303
|
+
style: { opacity: 0.7, fontSize: "0.875em" },
|
|
304
|
+
children: providerName
|
|
305
|
+
}
|
|
306
|
+
)
|
|
307
|
+
] })
|
|
308
|
+
] });
|
|
309
|
+
}
|
|
310
|
+
function SocialEmbed({
|
|
311
|
+
platform,
|
|
312
|
+
url,
|
|
313
|
+
embedCode,
|
|
314
|
+
oembed,
|
|
315
|
+
alignment = "center",
|
|
316
|
+
caption
|
|
317
|
+
}) {
|
|
318
|
+
var _a;
|
|
319
|
+
const containerRef = useRef2(null);
|
|
320
|
+
const html = useMemo(() => stripScripts(embedCode != null ? embedCode : oembed == null ? void 0 : oembed.html), [embedCode, oembed == null ? void 0 : oembed.html]);
|
|
321
|
+
useEffect3(() => {
|
|
322
|
+
var _a2;
|
|
323
|
+
if (!html) return;
|
|
324
|
+
(_a2 = containerRef.current) == null ? void 0 : _a2.querySelectorAll("iframe").forEach((iframe) => {
|
|
325
|
+
if (!iframe.hasAttribute("loading")) iframe.setAttribute("loading", "lazy");
|
|
326
|
+
});
|
|
327
|
+
const widget = WIDGET_SCRIPTS[platform];
|
|
328
|
+
if (!widget) return;
|
|
329
|
+
let cancelled = false;
|
|
330
|
+
void loadWidgetScript(widget.src, platform).then(() => {
|
|
331
|
+
const container = containerRef.current;
|
|
332
|
+
if (cancelled || !container) return;
|
|
333
|
+
if (!widget.process(container)) reinjectWidgetScript(widget.src, platform);
|
|
334
|
+
});
|
|
335
|
+
return () => {
|
|
336
|
+
cancelled = true;
|
|
337
|
+
};
|
|
338
|
+
}, [platform, html]);
|
|
339
|
+
const providerName = (_a = oembed == null ? void 0 : oembed.providerName) != null ? _a : PLATFORM_LABELS[platform];
|
|
340
|
+
const ariaLabel = (oembed == null ? void 0 : oembed.author) ? `${providerName} post by ${oembed.author}` : `${providerName} post`;
|
|
341
|
+
const figureStyle = {
|
|
342
|
+
margin: alignment === "center" ? "1rem auto" : "1rem 0",
|
|
343
|
+
textAlign: alignment
|
|
344
|
+
};
|
|
345
|
+
return /* @__PURE__ */ jsxs2(
|
|
346
|
+
"figure",
|
|
347
|
+
{
|
|
348
|
+
className: `bb-social-embed bb-social-embed-${platform} social-embed align-${alignment}`,
|
|
349
|
+
"aria-label": ariaLabel,
|
|
350
|
+
style: figureStyle,
|
|
351
|
+
children: [
|
|
352
|
+
html ? /* @__PURE__ */ jsx3(
|
|
353
|
+
"div",
|
|
354
|
+
{
|
|
355
|
+
ref: containerRef,
|
|
356
|
+
className: "bb-social-embed-html",
|
|
357
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
358
|
+
}
|
|
359
|
+
) : /* @__PURE__ */ jsx3(FallbackCard, { url, oembed, providerName }),
|
|
360
|
+
caption && /* @__PURE__ */ jsx3("figcaption", { className: "bb-social-embed-caption", children: caption })
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// src/Video.tsx
|
|
367
|
+
import {
|
|
368
|
+
useEffect as useEffect4,
|
|
369
|
+
useRef as useRef3,
|
|
370
|
+
useState as useState3
|
|
371
|
+
} from "react";
|
|
372
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
373
|
+
var HLS_MANIFEST = /\.m3u8(?:[?#]|$)/i;
|
|
374
|
+
var DASH_MANIFEST = /\.mpd(?:[?#]|$)/i;
|
|
375
|
+
var MuxPlayer = "mux-player";
|
|
376
|
+
function Video({
|
|
377
|
+
provider,
|
|
378
|
+
url,
|
|
379
|
+
playbackId,
|
|
380
|
+
poster,
|
|
381
|
+
title,
|
|
382
|
+
caption,
|
|
383
|
+
transcript,
|
|
384
|
+
player,
|
|
385
|
+
alignment = "center",
|
|
386
|
+
aspectRatio,
|
|
387
|
+
customAspectRatio,
|
|
388
|
+
instanceId
|
|
389
|
+
}) {
|
|
390
|
+
var _a, _b, _c, _d, _e;
|
|
391
|
+
const videoRef = useRef3(null);
|
|
392
|
+
const wantsMux = provider === "mux" && Boolean(playbackId);
|
|
393
|
+
const [muxDefined, setMuxDefined] = useState3(false);
|
|
394
|
+
useEffect4(() => {
|
|
395
|
+
if (!wantsMux || typeof window === "undefined" || !window.customElements) return;
|
|
396
|
+
if (window.customElements.get("mux-player")) {
|
|
397
|
+
setMuxDefined(true);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
let cancelled = false;
|
|
401
|
+
void window.customElements.whenDefined("mux-player").then(() => {
|
|
402
|
+
if (!cancelled) setMuxDefined(true);
|
|
403
|
+
});
|
|
404
|
+
return () => {
|
|
405
|
+
cancelled = true;
|
|
406
|
+
};
|
|
407
|
+
}, [wantsMux]);
|
|
408
|
+
const isHls = HLS_MANIFEST.test(url);
|
|
409
|
+
const isStreaming = isHls || DASH_MANIFEST.test(url);
|
|
410
|
+
const useMux = wantsMux && muxDefined;
|
|
411
|
+
useEffect4(() => {
|
|
412
|
+
var _a2;
|
|
413
|
+
const video = videoRef.current;
|
|
414
|
+
if (!video || !isHls) return;
|
|
415
|
+
const Hls = window.Hls;
|
|
416
|
+
if (!Hls || ((_a2 = Hls.isSupported) == null ? void 0 : _a2.call(Hls)) === false) return;
|
|
417
|
+
let instance;
|
|
418
|
+
try {
|
|
419
|
+
instance = new Hls();
|
|
420
|
+
instance.loadSource(url);
|
|
421
|
+
instance.attachMedia(video);
|
|
422
|
+
} catch (e) {
|
|
423
|
+
instance == null ? void 0 : instance.destroy();
|
|
424
|
+
instance = void 0;
|
|
425
|
+
}
|
|
426
|
+
return () => instance == null ? void 0 : instance.destroy();
|
|
427
|
+
}, [isHls, url, useMux]);
|
|
428
|
+
const capId = caption ? `bb-video-cap-${(_a = instanceId != null ? instanceId : playbackId) != null ? _a : 0}` : void 0;
|
|
429
|
+
const ratio = getAspectRatio(aspectRatio, customAspectRatio);
|
|
430
|
+
const frameStyle = getMediaFrameStyle(alignment, ratio);
|
|
431
|
+
const fillStyle = { width: "100%", height: "100%", display: "block" };
|
|
432
|
+
return /* @__PURE__ */ jsxs3(
|
|
433
|
+
"figure",
|
|
434
|
+
{
|
|
435
|
+
className: `bb-video align-${alignment}`,
|
|
436
|
+
style: getMediaFigureStyle(alignment),
|
|
437
|
+
"aria-label": title ? `Video: ${title}` : void 0,
|
|
438
|
+
children: [
|
|
439
|
+
title && /* @__PURE__ */ jsx4("figcaption", { className: "bb-video-title", style: { fontWeight: 600 }, children: title }),
|
|
440
|
+
/* @__PURE__ */ jsx4("div", { className: "bb-video-frame", style: frameStyle, children: useMux ? /* @__PURE__ */ jsx4(
|
|
441
|
+
MuxPlayer,
|
|
442
|
+
{
|
|
443
|
+
className: "bb-video-player",
|
|
444
|
+
"playback-id": playbackId,
|
|
445
|
+
poster,
|
|
446
|
+
"metadata-video-title": title,
|
|
447
|
+
autoplay: (player == null ? void 0 : player.autoplay) ? true : void 0,
|
|
448
|
+
loop: (player == null ? void 0 : player.loop) ? true : void 0,
|
|
449
|
+
muted: (player == null ? void 0 : player.muted) ? true : void 0,
|
|
450
|
+
"aria-describedby": capId,
|
|
451
|
+
style: fillStyle
|
|
452
|
+
}
|
|
453
|
+
) : /* @__PURE__ */ jsxs3(
|
|
454
|
+
"video",
|
|
455
|
+
{
|
|
456
|
+
ref: videoRef,
|
|
457
|
+
className: "bb-video-player",
|
|
458
|
+
src: url,
|
|
459
|
+
poster,
|
|
460
|
+
controls: (_b = player == null ? void 0 : player.controls) != null ? _b : true,
|
|
461
|
+
autoPlay: (_c = player == null ? void 0 : player.autoplay) != null ? _c : false,
|
|
462
|
+
loop: (_d = player == null ? void 0 : player.loop) != null ? _d : false,
|
|
463
|
+
muted: (_e = player == null ? void 0 : player.muted) != null ? _e : false,
|
|
464
|
+
playsInline: true,
|
|
465
|
+
preload: isStreaming ? "none" : "metadata",
|
|
466
|
+
"aria-label": title || "Video player",
|
|
467
|
+
"aria-describedby": capId,
|
|
468
|
+
style: fillStyle,
|
|
469
|
+
children: [
|
|
470
|
+
transcript && /* @__PURE__ */ jsx4("track", { kind: "captions", src: transcript, label: "Captions" }),
|
|
471
|
+
"Your browser does not support the video element. ",
|
|
472
|
+
/* @__PURE__ */ jsx4("a", { href: url, children: "Download the video" }),
|
|
473
|
+
"."
|
|
474
|
+
]
|
|
475
|
+
}
|
|
476
|
+
) }),
|
|
477
|
+
caption && /* @__PURE__ */ jsx4("figcaption", { id: capId, className: "bb-video-caption", style: MEDIA_CAPTION_STYLE, children: caption })
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// src/BlocksRenderer.tsx
|
|
484
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
485
|
+
function renderTextNode(node, key, modifiers) {
|
|
486
|
+
const marks = buildTextMarks(node);
|
|
487
|
+
let content = node.text;
|
|
488
|
+
for (let i = marks.length - 1; i >= 0; i -= 1) {
|
|
489
|
+
const mark = marks[i];
|
|
490
|
+
const Comp = modifiers == null ? void 0 : modifiers[mark.name];
|
|
491
|
+
if (Comp) {
|
|
492
|
+
content = /* @__PURE__ */ jsx5(Comp, { ...getModifierProps(mark), children: content });
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
const { tag, style } = getDefaultMarkRender(mark);
|
|
496
|
+
content = createElement(tag, { style }, content);
|
|
497
|
+
}
|
|
498
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: content }, key);
|
|
499
|
+
}
|
|
500
|
+
function renderMath(node, key, blocks) {
|
|
501
|
+
var _a;
|
|
502
|
+
const isBlock = node.format === "block";
|
|
503
|
+
const MathComp = blocks == null ? void 0 : blocks.math;
|
|
504
|
+
const formula = (_a = node.value) != null ? _a : "";
|
|
505
|
+
if (MathComp) {
|
|
506
|
+
return /* @__PURE__ */ jsx5(MathComp, { formula, inline: !isBlock }, key);
|
|
507
|
+
}
|
|
508
|
+
const Tag = isBlock ? "div" : "span";
|
|
509
|
+
const className = isBlock ? "katex-block" : "katex-inline";
|
|
510
|
+
try {
|
|
511
|
+
const html = katex.renderToString(formula, {
|
|
512
|
+
displayMode: isBlock,
|
|
513
|
+
throwOnError: false
|
|
514
|
+
});
|
|
515
|
+
return /* @__PURE__ */ jsx5(Tag, { className, dangerouslySetInnerHTML: { __html: html } }, key);
|
|
516
|
+
} catch (e) {
|
|
517
|
+
return /* @__PURE__ */ jsx5(Tag, { className, children: formula }, key);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function renderInlineContent(children, blocks, modifiers) {
|
|
521
|
+
return children.map((child, index) => {
|
|
522
|
+
if (child.type === "text") {
|
|
523
|
+
return renderTextNode(child, index, modifiers);
|
|
524
|
+
}
|
|
525
|
+
if (child.type === "math") {
|
|
526
|
+
return renderMath(child, index, blocks);
|
|
527
|
+
}
|
|
528
|
+
if (child.type === "link") {
|
|
529
|
+
const LinkComp = blocks == null ? void 0 : blocks.link;
|
|
530
|
+
const linkChildren = child.children.map(
|
|
531
|
+
(textNode, i) => renderTextNode(textNode, i, modifiers)
|
|
532
|
+
);
|
|
533
|
+
return LinkComp ? /* @__PURE__ */ jsx5(LinkComp, { url: child.url, target: child.target, rel: child.rel, children: linkChildren }, index) : /* @__PURE__ */ jsx5("a", { href: child.url, target: child.target, rel: child.rel, children: linkChildren }, index);
|
|
534
|
+
}
|
|
535
|
+
return null;
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
function renderListItem(node, key, isTodo, blocks, modifiers) {
|
|
539
|
+
var _a;
|
|
540
|
+
const ListItemComp = blocks == null ? void 0 : blocks["list-item"];
|
|
541
|
+
const children = renderInlineContent(node.children, blocks, modifiers);
|
|
542
|
+
if (ListItemComp) {
|
|
543
|
+
return /* @__PURE__ */ jsx5(ListItemComp, { checked: isTodo ? node.checked : void 0, children }, key);
|
|
544
|
+
}
|
|
545
|
+
if (isTodo) {
|
|
546
|
+
const checked = (_a = node.checked) != null ? _a : false;
|
|
547
|
+
return /* @__PURE__ */ jsxs4("li", { style: { listStyle: "none" }, children: [
|
|
548
|
+
/* @__PURE__ */ jsx5("input", { type: "checkbox", checked, readOnly: true, style: { marginRight: "0.5em" } }),
|
|
549
|
+
/* @__PURE__ */ jsx5("span", { style: checked ? { textDecoration: "line-through", opacity: 0.6 } : void 0, children })
|
|
550
|
+
] }, key);
|
|
551
|
+
}
|
|
552
|
+
return /* @__PURE__ */ jsx5("li", { children }, key);
|
|
553
|
+
}
|
|
554
|
+
function renderList(node, key, blocks, modifiers) {
|
|
555
|
+
const ListComp = blocks == null ? void 0 : blocks.list;
|
|
556
|
+
const indentLevel = node.indentLevel || 0;
|
|
557
|
+
const isTodo = node.format === "todo";
|
|
558
|
+
const children = node.children.map((child, index) => {
|
|
559
|
+
if (child.type === "list-item") {
|
|
560
|
+
return renderListItem(child, index, isTodo, blocks, modifiers);
|
|
561
|
+
}
|
|
562
|
+
if (child.type === "list") {
|
|
563
|
+
return renderList(child, index, blocks, modifiers);
|
|
564
|
+
}
|
|
565
|
+
return null;
|
|
566
|
+
});
|
|
567
|
+
if (ListComp) {
|
|
568
|
+
return /* @__PURE__ */ jsx5(ListComp, { format: node.format, indentLevel, children }, key);
|
|
569
|
+
}
|
|
570
|
+
if (isTodo) {
|
|
571
|
+
return /* @__PURE__ */ jsx5("ul", { style: { listStyle: "none", paddingLeft: indentLevel > 0 ? "1.5em" : 0 }, children }, key);
|
|
572
|
+
}
|
|
573
|
+
const Tag = node.format === "ordered" ? "ol" : "ul";
|
|
574
|
+
const listStyleType = getListStyleType(node.format, indentLevel);
|
|
575
|
+
return /* @__PURE__ */ jsx5(Tag, { style: { listStyleType }, children }, key);
|
|
576
|
+
}
|
|
577
|
+
function renderTable(block, key, blocks, modifiers) {
|
|
578
|
+
const TableComp = blocks == null ? void 0 : blocks.table;
|
|
579
|
+
const RowComp = blocks == null ? void 0 : blocks["table-row"];
|
|
580
|
+
const CellComp = blocks == null ? void 0 : blocks["table-cell"];
|
|
581
|
+
const HeaderCellComp = blocks == null ? void 0 : blocks["table-header-cell"];
|
|
582
|
+
let headerRowCount = 0;
|
|
583
|
+
while (isHeaderRow(block.children[headerRowCount])) headerRowCount++;
|
|
584
|
+
const rows = block.children.map((row, rowIndex) => {
|
|
585
|
+
const inHeader = rowIndex < headerRowCount;
|
|
586
|
+
const cells = row.children.map((cell, cellIndex) => {
|
|
587
|
+
const cellChildren = renderInlineContent(cell.children, blocks, modifiers);
|
|
588
|
+
const isHeader = cell.type === "table-header-cell";
|
|
589
|
+
const style = cell.align ? { textAlign: cell.align } : void 0;
|
|
590
|
+
const cellProps = {
|
|
591
|
+
align: cell.align,
|
|
592
|
+
colSpan: cell.colSpan,
|
|
593
|
+
rowSpan: cell.rowSpan,
|
|
594
|
+
style
|
|
595
|
+
};
|
|
596
|
+
if (isHeader && HeaderCellComp) {
|
|
597
|
+
return /* @__PURE__ */ jsx5(HeaderCellComp, { ...cellProps, children: cellChildren }, cellIndex);
|
|
598
|
+
}
|
|
599
|
+
if (!isHeader && CellComp) {
|
|
600
|
+
return /* @__PURE__ */ jsx5(CellComp, { ...cellProps, children: cellChildren }, cellIndex);
|
|
601
|
+
}
|
|
602
|
+
return isHeader ? /* @__PURE__ */ jsx5(
|
|
603
|
+
"th",
|
|
604
|
+
{
|
|
605
|
+
scope: inHeader ? "col" : "row",
|
|
606
|
+
colSpan: cell.colSpan,
|
|
607
|
+
rowSpan: cell.rowSpan,
|
|
608
|
+
style,
|
|
609
|
+
children: cellChildren
|
|
610
|
+
},
|
|
611
|
+
cellIndex
|
|
612
|
+
) : /* @__PURE__ */ jsx5("td", { colSpan: cell.colSpan, rowSpan: cell.rowSpan, style, children: cellChildren }, cellIndex);
|
|
613
|
+
});
|
|
614
|
+
return RowComp ? /* @__PURE__ */ jsx5(RowComp, { children: cells }, rowIndex) : /* @__PURE__ */ jsx5("tr", { children: cells }, rowIndex);
|
|
615
|
+
});
|
|
616
|
+
if (TableComp) {
|
|
617
|
+
return /* @__PURE__ */ jsx5(TableComp, { children: rows }, key);
|
|
618
|
+
}
|
|
619
|
+
return /* @__PURE__ */ jsxs4("table", { className: "bb-table", children: [
|
|
620
|
+
headerRowCount > 0 && /* @__PURE__ */ jsx5("thead", { children: rows.slice(0, headerRowCount) }),
|
|
621
|
+
rows.length > headerRowCount && /* @__PURE__ */ jsx5("tbody", { children: rows.slice(headerRowCount) })
|
|
622
|
+
] }, key);
|
|
623
|
+
}
|
|
624
|
+
function isHeaderRow(row) {
|
|
625
|
+
return !!row && row.children.length > 0 && row.children.every((c) => c.type === "table-header-cell");
|
|
626
|
+
}
|
|
627
|
+
function renderBlock(block, key, blocks, modifiers, options) {
|
|
628
|
+
switch (block.type) {
|
|
629
|
+
case "paragraph":
|
|
630
|
+
return renderParagraph(block, key, blocks, modifiers);
|
|
631
|
+
case "heading":
|
|
632
|
+
return renderHeading(block, key, blocks, modifiers);
|
|
633
|
+
case "list":
|
|
634
|
+
return renderList(block, key, blocks, modifiers);
|
|
635
|
+
case "quote":
|
|
636
|
+
return renderQuote(block, key, blocks, modifiers);
|
|
637
|
+
case "code":
|
|
638
|
+
return renderCode(block, key, blocks, options);
|
|
639
|
+
case "image":
|
|
640
|
+
return renderImage(block, key, blocks);
|
|
641
|
+
case "horizontal-line":
|
|
642
|
+
return renderHorizontalLine(block, key, blocks);
|
|
643
|
+
case "table":
|
|
644
|
+
return renderTable(block, key, blocks, modifiers);
|
|
645
|
+
case "media-embed":
|
|
646
|
+
return renderMediaEmbed(block, key, blocks);
|
|
647
|
+
case "embed":
|
|
648
|
+
return renderEmbed(block, key, blocks);
|
|
649
|
+
case "video":
|
|
650
|
+
return renderVideo(block, key, blocks);
|
|
651
|
+
case "math":
|
|
652
|
+
return renderMath(block, key, blocks);
|
|
653
|
+
case "diagram":
|
|
654
|
+
return renderDiagram(block, key, blocks);
|
|
655
|
+
case "callout":
|
|
656
|
+
return renderCallout(block, key, blocks, modifiers, options);
|
|
657
|
+
case "details":
|
|
658
|
+
return renderDetails(block, key, blocks, modifiers, options);
|
|
659
|
+
case "button":
|
|
660
|
+
return renderButton(block, key, blocks);
|
|
661
|
+
case "social-embed":
|
|
662
|
+
return renderSocialEmbed(block, key, blocks);
|
|
663
|
+
case "audio":
|
|
664
|
+
return renderAudio(block, key, blocks);
|
|
665
|
+
default:
|
|
666
|
+
return null;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
function getBlockStyle(block) {
|
|
670
|
+
return coreGetBlockStyle(block);
|
|
671
|
+
}
|
|
672
|
+
function renderParagraph(block, key, blocks, modifiers) {
|
|
673
|
+
const ParagraphComp = blocks == null ? void 0 : blocks.paragraph;
|
|
674
|
+
const children = renderInlineContent(block.children, blocks, modifiers);
|
|
675
|
+
const style = getBlockStyle(block);
|
|
676
|
+
return ParagraphComp ? /* @__PURE__ */ jsx5(ParagraphComp, { style, children }, key) : /* @__PURE__ */ jsx5("p", { style, children }, key);
|
|
677
|
+
}
|
|
678
|
+
function renderHeading(block, key, blocks, modifiers) {
|
|
679
|
+
const HeadingComp = blocks == null ? void 0 : blocks.heading;
|
|
680
|
+
const children = renderInlineContent(block.children, blocks, modifiers);
|
|
681
|
+
const style = getBlockStyle(block);
|
|
682
|
+
if (HeadingComp) {
|
|
683
|
+
return /* @__PURE__ */ jsx5(HeadingComp, { level: block.level, style, children }, key);
|
|
684
|
+
}
|
|
685
|
+
const Tag = `h${block.level}`;
|
|
686
|
+
return /* @__PURE__ */ jsx5(Tag, { style, children }, key);
|
|
687
|
+
}
|
|
688
|
+
function renderQuote(block, key, blocks, modifiers) {
|
|
689
|
+
const QuoteComp = blocks == null ? void 0 : blocks.quote;
|
|
690
|
+
const children = renderInlineContent(block.children, blocks, modifiers);
|
|
691
|
+
const style = getBlockStyle(block);
|
|
692
|
+
return QuoteComp ? /* @__PURE__ */ jsx5(QuoteComp, { style, children }, key) : /* @__PURE__ */ jsx5("blockquote", { className: "bb-quote", style, children }, key);
|
|
693
|
+
}
|
|
694
|
+
var DEFAULT_CODE_THEME = "github-dark";
|
|
695
|
+
function renderCode(block, key, blocks, options) {
|
|
696
|
+
var _a, _b;
|
|
697
|
+
const CodeComp = blocks == null ? void 0 : blocks.code;
|
|
698
|
+
const plainText = getPlainText(block.children);
|
|
699
|
+
if (CodeComp) {
|
|
700
|
+
return /* @__PURE__ */ jsx5(CodeComp, { plainText, language: block.language, children: plainText }, key);
|
|
701
|
+
}
|
|
702
|
+
return /* @__PURE__ */ jsx5(
|
|
703
|
+
CodeBlock,
|
|
704
|
+
{
|
|
705
|
+
plainText,
|
|
706
|
+
language: block.language,
|
|
707
|
+
theme: (_a = options == null ? void 0 : options.codeTheme) != null ? _a : DEFAULT_CODE_THEME,
|
|
708
|
+
copyButton: (_b = options == null ? void 0 : options.codeCopyButton) != null ? _b : false
|
|
709
|
+
},
|
|
710
|
+
key
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
var TABLE_CSS = ".bb-table{display:block;width:max-content;max-width:100%;margin:1rem 0;overflow:auto;border-collapse:collapse;border-spacing:0;border:1px solid var(--bb-table-border,#d0d7de)}.bb-table th,.bb-table td{padding:.375rem .8125rem;border:1px solid var(--bb-table-border,#d0d7de);text-align:left}.bb-table th{font-weight:600;background:var(--bb-table-header-bg,#f6f8fa)}.bb-table tbody tr{background:var(--bb-table-row-bg,#fff)}.bb-table tbody tr:nth-child(2n){background:var(--bb-table-stripe-bg,#f6f8fa)}";
|
|
714
|
+
var QUOTE_CSS = ".bb-quote{margin:1rem 0;padding:0 1rem;color:var(--bb-quote-fg,#57606a);border-left:.25rem solid var(--bb-quote-border,#d0d7de)}";
|
|
715
|
+
var CODE_CSS = ".bb-code{position:relative;margin:1rem 0}.bb-code pre{margin:0;padding:1rem;border-radius:6px;font-size:.875rem;line-height:1.45;tab-size:2;overflow-x:auto}.bb-code-pre{background:var(--bb-code-fallback-bg,#24292e);color:var(--bb-code-fallback-fg,#e1e4e8)}.bb-code-copy{position:absolute;top:.5rem;right:.5rem;padding:.25rem .5rem;font-size:.75rem;line-height:1;color:var(--bb-code-copy-fg,#e1e4e8);background:var(--bb-code-copy-bg,rgba(110,118,129,.4));border:1px solid var(--bb-code-copy-border,rgba(240,246,252,.1));border-radius:6px;cursor:pointer;opacity:0;transition:opacity .15s ease,background .15s ease}.bb-code:hover .bb-code-copy,.bb-code-copy:focus-visible{opacity:1}.bb-code-copy:hover{background:var(--bb-code-copy-hover-bg,rgba(110,118,129,.6))}";
|
|
716
|
+
function renderImage(block, key, blocks) {
|
|
717
|
+
const ImageComp = blocks == null ? void 0 : blocks.image;
|
|
718
|
+
if (ImageComp) {
|
|
719
|
+
return /* @__PURE__ */ jsx5(
|
|
720
|
+
ImageComp,
|
|
721
|
+
{
|
|
722
|
+
image: block.image,
|
|
723
|
+
caption: block.caption,
|
|
724
|
+
imageAlign: block.imageAlign
|
|
725
|
+
},
|
|
726
|
+
key
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
const align = block.imageAlign || "center";
|
|
730
|
+
const alignStyle = {
|
|
731
|
+
textAlign: align
|
|
732
|
+
};
|
|
733
|
+
return /* @__PURE__ */ jsxs4("figure", { style: alignStyle, children: [
|
|
734
|
+
/* @__PURE__ */ jsx5(
|
|
735
|
+
"img",
|
|
736
|
+
{
|
|
737
|
+
src: block.image.url,
|
|
738
|
+
alt: block.image.alternativeText || "",
|
|
739
|
+
width: block.image.width,
|
|
740
|
+
height: block.image.height
|
|
741
|
+
}
|
|
742
|
+
),
|
|
743
|
+
block.caption && /* @__PURE__ */ jsx5("figcaption", { children: block.caption })
|
|
744
|
+
] }, key);
|
|
745
|
+
}
|
|
746
|
+
function renderHorizontalLine(_block, key, blocks) {
|
|
747
|
+
const HrComp = blocks == null ? void 0 : blocks["horizontal-line"];
|
|
748
|
+
return HrComp ? /* @__PURE__ */ jsx5(HrComp, {}, key) : /* @__PURE__ */ jsx5("hr", {}, key);
|
|
749
|
+
}
|
|
750
|
+
function renderMediaEmbed(block, key, blocks) {
|
|
751
|
+
const EmbedComp = blocks == null ? void 0 : blocks["media-embed"];
|
|
752
|
+
if (EmbedComp) {
|
|
753
|
+
return /* @__PURE__ */ jsx5(EmbedComp, { url: block.url, originalUrl: block.originalUrl }, key);
|
|
754
|
+
}
|
|
755
|
+
return /* @__PURE__ */ jsx5("div", { style: { position: "relative", paddingBottom: "56.25%", height: 0 }, children: /* @__PURE__ */ jsx5(
|
|
756
|
+
"iframe",
|
|
757
|
+
{
|
|
758
|
+
src: block.url,
|
|
759
|
+
style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", border: 0 },
|
|
760
|
+
allowFullScreen: true,
|
|
761
|
+
title: "Embedded media"
|
|
762
|
+
}
|
|
763
|
+
) }, key);
|
|
764
|
+
}
|
|
765
|
+
var EMBED_FRAME_CSS = ".bb-embed-frame{overflow:hidden}.bb-embed-frame iframe{width:100%;height:100%;border:0;display:block}";
|
|
766
|
+
function renderEmbed(block, key, blocks) {
|
|
767
|
+
var _a;
|
|
768
|
+
const EmbedComp = blocks == null ? void 0 : blocks.embed;
|
|
769
|
+
if (EmbedComp) {
|
|
770
|
+
return /* @__PURE__ */ jsx5(
|
|
771
|
+
EmbedComp,
|
|
772
|
+
{
|
|
773
|
+
source: block.source,
|
|
774
|
+
url: block.url,
|
|
775
|
+
iframe: block.iframe,
|
|
776
|
+
embedHtml: block.embedHtml,
|
|
777
|
+
embedSrc: block.embedSrc,
|
|
778
|
+
provider: block.provider,
|
|
779
|
+
thumbnail: block.thumbnail,
|
|
780
|
+
aspectRatio: block.aspectRatio,
|
|
781
|
+
customAspectRatio: block.customAspectRatio,
|
|
782
|
+
alignment: block.alignment,
|
|
783
|
+
caption: block.caption,
|
|
784
|
+
title: block.title
|
|
785
|
+
},
|
|
786
|
+
key
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
const alignment = (_a = block.alignment) != null ? _a : "center";
|
|
790
|
+
const ratio = getAspectRatio(block.aspectRatio, block.customAspectRatio);
|
|
791
|
+
const body = block.embedHtml ? /* @__PURE__ */ jsx5(
|
|
792
|
+
"div",
|
|
793
|
+
{
|
|
794
|
+
className: "bb-embed-frame",
|
|
795
|
+
style: getMediaFrameStyle(alignment, ratio),
|
|
796
|
+
dangerouslySetInnerHTML: { __html: block.embedHtml }
|
|
797
|
+
}
|
|
798
|
+
) : block.url ? /* @__PURE__ */ jsx5("a", { className: "bb-embed-fallback", href: block.url, target: "_blank", rel: "noopener noreferrer", children: block.title || block.url }) : null;
|
|
799
|
+
if (!body) return null;
|
|
800
|
+
return /* @__PURE__ */ jsxs4(
|
|
801
|
+
"figure",
|
|
802
|
+
{
|
|
803
|
+
className: `bb-embed align-${alignment}`,
|
|
804
|
+
style: getMediaFigureStyle(alignment),
|
|
805
|
+
"aria-label": block.title,
|
|
806
|
+
children: [
|
|
807
|
+
body,
|
|
808
|
+
block.caption && /* @__PURE__ */ jsx5("figcaption", { className: "bb-embed-caption", style: MEDIA_CAPTION_STYLE, children: block.caption })
|
|
809
|
+
]
|
|
810
|
+
},
|
|
811
|
+
key
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
function renderVideo(block, key, blocks) {
|
|
815
|
+
var _a, _b, _c, _d;
|
|
816
|
+
const VideoComp = blocks == null ? void 0 : blocks.video;
|
|
817
|
+
if (VideoComp) {
|
|
818
|
+
return /* @__PURE__ */ jsx5(
|
|
819
|
+
VideoComp,
|
|
820
|
+
{
|
|
821
|
+
provider: block.provider,
|
|
822
|
+
url: (_a = block.url) != null ? _a : "",
|
|
823
|
+
assetId: block.assetId,
|
|
824
|
+
playbackId: block.playbackId,
|
|
825
|
+
file: block.file,
|
|
826
|
+
poster: block.poster,
|
|
827
|
+
title: block.title,
|
|
828
|
+
caption: block.caption,
|
|
829
|
+
transcript: block.transcript,
|
|
830
|
+
player: block.player,
|
|
831
|
+
alignment: block.alignment,
|
|
832
|
+
aspectRatio: block.aspectRatio,
|
|
833
|
+
customAspectRatio: block.customAspectRatio
|
|
834
|
+
},
|
|
835
|
+
key
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
return /* @__PURE__ */ jsx5(
|
|
839
|
+
Video,
|
|
840
|
+
{
|
|
841
|
+
provider: block.provider,
|
|
842
|
+
url: (_b = block.url) != null ? _b : "",
|
|
843
|
+
assetId: block.assetId,
|
|
844
|
+
playbackId: block.playbackId,
|
|
845
|
+
file: block.file,
|
|
846
|
+
poster: block.poster,
|
|
847
|
+
title: block.title,
|
|
848
|
+
caption: block.caption,
|
|
849
|
+
transcript: block.transcript,
|
|
850
|
+
player: block.player,
|
|
851
|
+
alignment: block.alignment,
|
|
852
|
+
aspectRatio: block.aspectRatio,
|
|
853
|
+
customAspectRatio: block.customAspectRatio,
|
|
854
|
+
instanceId: (_d = (_c = block.file) == null ? void 0 : _c.id) != null ? _d : key
|
|
855
|
+
},
|
|
856
|
+
key
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
function renderSocialEmbed(block, key, blocks) {
|
|
860
|
+
const SocialComp = blocks == null ? void 0 : blocks["social-embed"];
|
|
861
|
+
if (SocialComp) {
|
|
862
|
+
return /* @__PURE__ */ jsx5(
|
|
863
|
+
SocialComp,
|
|
864
|
+
{
|
|
865
|
+
platform: block.platform,
|
|
866
|
+
url: block.url,
|
|
867
|
+
embedCode: block.embedCode,
|
|
868
|
+
oembed: block.oembed,
|
|
869
|
+
alignment: block.alignment,
|
|
870
|
+
caption: block.caption
|
|
871
|
+
},
|
|
872
|
+
key
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
return /* @__PURE__ */ jsx5(
|
|
876
|
+
SocialEmbed,
|
|
877
|
+
{
|
|
878
|
+
platform: block.platform,
|
|
879
|
+
url: block.url,
|
|
880
|
+
embedCode: block.embedCode,
|
|
881
|
+
oembed: block.oembed,
|
|
882
|
+
alignment: block.alignment,
|
|
883
|
+
caption: block.caption
|
|
884
|
+
},
|
|
885
|
+
key
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
var AUDIO_ALIGN_ITEMS = {
|
|
889
|
+
left: "flex-start",
|
|
890
|
+
center: "center",
|
|
891
|
+
right: "flex-end",
|
|
892
|
+
none: "stretch"
|
|
893
|
+
};
|
|
894
|
+
function renderAudio(block, key, blocks) {
|
|
895
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
896
|
+
const AudioComp = blocks == null ? void 0 : blocks.audio;
|
|
897
|
+
if (AudioComp) {
|
|
898
|
+
return /* @__PURE__ */ jsx5(
|
|
899
|
+
AudioComp,
|
|
900
|
+
{
|
|
901
|
+
file: block.file,
|
|
902
|
+
title: block.title,
|
|
903
|
+
caption: block.caption,
|
|
904
|
+
player: (_a = block.player) != null ? _a : {},
|
|
905
|
+
alignment: block.alignment
|
|
906
|
+
},
|
|
907
|
+
key
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
const { file, title, caption } = block;
|
|
911
|
+
const player = (_b = block.player) != null ? _b : {};
|
|
912
|
+
const alignment = (_c = block.alignment) != null ? _c : "center";
|
|
913
|
+
const capId = caption ? `bb-audio-cap-${(_e = (_d = file.id) != null ? _d : file.hash) != null ? _e : key}` : void 0;
|
|
914
|
+
return /* @__PURE__ */ jsxs4(
|
|
915
|
+
"figure",
|
|
916
|
+
{
|
|
917
|
+
className: `bb-audio align-${alignment}`,
|
|
918
|
+
style: {
|
|
919
|
+
display: "flex",
|
|
920
|
+
flexDirection: "column",
|
|
921
|
+
gap: "0.5rem",
|
|
922
|
+
margin: "1rem 0",
|
|
923
|
+
alignItems: AUDIO_ALIGN_ITEMS[alignment]
|
|
924
|
+
},
|
|
925
|
+
children: [
|
|
926
|
+
title && /* @__PURE__ */ jsx5("figcaption", { className: "bb-audio-title", style: { fontWeight: 600 }, children: title }),
|
|
927
|
+
/* @__PURE__ */ jsxs4(
|
|
928
|
+
"audio",
|
|
929
|
+
{
|
|
930
|
+
className: "bb-audio-player",
|
|
931
|
+
src: file.url,
|
|
932
|
+
controls: (_f = player.controls) != null ? _f : true,
|
|
933
|
+
autoPlay: (_g = player.autoplay) != null ? _g : false,
|
|
934
|
+
loop: (_h = player.loop) != null ? _h : false,
|
|
935
|
+
preload: (_i = player.preload) != null ? _i : "metadata",
|
|
936
|
+
"aria-label": title || "Audio player",
|
|
937
|
+
"aria-describedby": capId,
|
|
938
|
+
style: { width: "100%", maxWidth: alignment === "none" ? "100%" : "32rem" },
|
|
939
|
+
children: [
|
|
940
|
+
"Your browser does not support the audio element. ",
|
|
941
|
+
/* @__PURE__ */ jsx5("a", { href: file.url, children: "Download the audio" }),
|
|
942
|
+
"."
|
|
943
|
+
]
|
|
944
|
+
}
|
|
945
|
+
),
|
|
946
|
+
caption && /* @__PURE__ */ jsx5(
|
|
947
|
+
"figcaption",
|
|
948
|
+
{
|
|
949
|
+
id: capId,
|
|
950
|
+
className: "bb-audio-caption",
|
|
951
|
+
style: { fontSize: "0.875rem", color: "#6b7280" },
|
|
952
|
+
children: caption
|
|
953
|
+
}
|
|
954
|
+
)
|
|
955
|
+
]
|
|
956
|
+
},
|
|
957
|
+
key
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
function renderDiagram(block, key, blocks) {
|
|
961
|
+
var _a;
|
|
962
|
+
const DiagramComp = blocks == null ? void 0 : blocks.diagram;
|
|
963
|
+
const code = (_a = block.value) != null ? _a : "";
|
|
964
|
+
if (DiagramComp) {
|
|
965
|
+
return /* @__PURE__ */ jsx5(DiagramComp, { code, format: block.format }, key);
|
|
966
|
+
}
|
|
967
|
+
return /* @__PURE__ */ jsx5(MermaidDiagram, { value: code }, key);
|
|
968
|
+
}
|
|
969
|
+
var CALLOUT_VARIANTS = {
|
|
970
|
+
note: {
|
|
971
|
+
color: "#0969da",
|
|
972
|
+
label: "Note",
|
|
973
|
+
icon: "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
|
|
974
|
+
},
|
|
975
|
+
tip: {
|
|
976
|
+
color: "#1a7f37",
|
|
977
|
+
label: "Tip",
|
|
978
|
+
icon: "M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"
|
|
979
|
+
},
|
|
980
|
+
important: {
|
|
981
|
+
color: "#8250df",
|
|
982
|
+
label: "Important",
|
|
983
|
+
icon: "M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
|
|
984
|
+
},
|
|
985
|
+
warning: {
|
|
986
|
+
color: "#9a6700",
|
|
987
|
+
label: "Warning",
|
|
988
|
+
icon: "M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
|
|
989
|
+
},
|
|
990
|
+
caution: {
|
|
991
|
+
color: "#d1242f",
|
|
992
|
+
label: "Caution",
|
|
993
|
+
icon: "M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .39.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.39.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
function renderCallout(block, key, blocks, modifiers, options) {
|
|
997
|
+
var _a;
|
|
998
|
+
const variant = CALLOUT_VARIANTS[block.variant] ? block.variant : "note";
|
|
999
|
+
const meta = CALLOUT_VARIANTS[variant];
|
|
1000
|
+
const childNodes = block.children.map(
|
|
1001
|
+
(child, index) => renderBlock(child, index, blocks, modifiers, options)
|
|
1002
|
+
);
|
|
1003
|
+
const lastIndex = childNodes.length - 1;
|
|
1004
|
+
const children = childNodes.map((node, index) => {
|
|
1005
|
+
if (!isValidElement(node)) return node;
|
|
1006
|
+
const element = node;
|
|
1007
|
+
const collapsed = {};
|
|
1008
|
+
if (index === 0) collapsed.marginTop = 0;
|
|
1009
|
+
if (index === lastIndex) collapsed.marginBottom = 0;
|
|
1010
|
+
return cloneElement(element, { style: { ...element.props.style, ...collapsed } });
|
|
1011
|
+
});
|
|
1012
|
+
const CalloutComp = blocks == null ? void 0 : blocks.callout;
|
|
1013
|
+
if (CalloutComp) {
|
|
1014
|
+
return /* @__PURE__ */ jsx5(CalloutComp, { variant, title: block.title, children }, key);
|
|
1015
|
+
}
|
|
1016
|
+
const title = ((_a = block.title) == null ? void 0 : _a.trim()) ? block.title : meta.label;
|
|
1017
|
+
return /* @__PURE__ */ jsxs4(
|
|
1018
|
+
"aside",
|
|
1019
|
+
{
|
|
1020
|
+
className: `bb-callout bb-callout-${variant}`,
|
|
1021
|
+
role: "note",
|
|
1022
|
+
style: {
|
|
1023
|
+
borderLeft: `0.25rem solid ${meta.color}`,
|
|
1024
|
+
// Subtle accent-tinted background (~8% opacity) to match the editor preview.
|
|
1025
|
+
backgroundColor: `${meta.color}14`,
|
|
1026
|
+
padding: "0.5rem 1rem",
|
|
1027
|
+
margin: "1rem 0"
|
|
1028
|
+
},
|
|
1029
|
+
children: [
|
|
1030
|
+
/* @__PURE__ */ jsxs4(
|
|
1031
|
+
"p",
|
|
1032
|
+
{
|
|
1033
|
+
className: "bb-callout-title",
|
|
1034
|
+
style: {
|
|
1035
|
+
display: "flex",
|
|
1036
|
+
alignItems: "center",
|
|
1037
|
+
gap: "0.5rem",
|
|
1038
|
+
// GitHub spacing: tight title line with a 1rem gap before the body.
|
|
1039
|
+
lineHeight: 1,
|
|
1040
|
+
margin: "0 0 1rem",
|
|
1041
|
+
fontWeight: 600,
|
|
1042
|
+
color: meta.color
|
|
1043
|
+
},
|
|
1044
|
+
children: [
|
|
1045
|
+
/* @__PURE__ */ jsx5(
|
|
1046
|
+
"svg",
|
|
1047
|
+
{
|
|
1048
|
+
className: "bb-callout-icon",
|
|
1049
|
+
viewBox: "0 0 16 16",
|
|
1050
|
+
width: "16",
|
|
1051
|
+
height: "16",
|
|
1052
|
+
fill: "currentColor",
|
|
1053
|
+
"aria-hidden": "true",
|
|
1054
|
+
children: /* @__PURE__ */ jsx5("path", { d: meta.icon })
|
|
1055
|
+
}
|
|
1056
|
+
),
|
|
1057
|
+
title
|
|
1058
|
+
]
|
|
1059
|
+
}
|
|
1060
|
+
),
|
|
1061
|
+
children
|
|
1062
|
+
]
|
|
1063
|
+
},
|
|
1064
|
+
key
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
function renderDetails(block, key, blocks, modifiers, options) {
|
|
1068
|
+
const children = block.children.map(
|
|
1069
|
+
(child, index) => renderBlock(child, index, blocks, modifiers, options)
|
|
1070
|
+
);
|
|
1071
|
+
const DetailsComp = blocks == null ? void 0 : blocks.details;
|
|
1072
|
+
if (DetailsComp) {
|
|
1073
|
+
return /* @__PURE__ */ jsx5(DetailsComp, { summary: block.summary, defaultOpen: block.defaultOpen, children }, key);
|
|
1074
|
+
}
|
|
1075
|
+
return /* @__PURE__ */ jsxs4("details", { className: "bb-details", open: block.defaultOpen, children: [
|
|
1076
|
+
/* @__PURE__ */ jsx5("summary", { className: "bb-details-summary", children: block.summary }),
|
|
1077
|
+
children
|
|
1078
|
+
] }, key);
|
|
1079
|
+
}
|
|
1080
|
+
var BUTTON_HOVER_CSS = ".bb-button{transition:background-color .15s ease,color .15s ease}.bb-button:hover{background-color:var(--bb-button-hover-bg,var(--bb-button-bg))!important;color:var(--bb-button-hover-color,var(--bb-button-color))!important}.bb-button:focus-visible{outline:2px solid currentColor;outline-offset:2px}";
|
|
1081
|
+
function contentHasBlock(nodes, type) {
|
|
1082
|
+
for (const node of nodes) {
|
|
1083
|
+
if (node.type === type) return true;
|
|
1084
|
+
const children = node.children;
|
|
1085
|
+
if (Array.isArray(children) && contentHasBlock(children, type)) return true;
|
|
1086
|
+
}
|
|
1087
|
+
return false;
|
|
1088
|
+
}
|
|
1089
|
+
function getButtonStyle(style) {
|
|
1090
|
+
const out = {
|
|
1091
|
+
display: "inline-block",
|
|
1092
|
+
textDecoration: "none",
|
|
1093
|
+
cursor: "pointer"
|
|
1094
|
+
};
|
|
1095
|
+
if (!style) return out;
|
|
1096
|
+
if (style.backgroundColor) {
|
|
1097
|
+
out.backgroundColor = style.backgroundColor;
|
|
1098
|
+
out["--bb-button-bg"] = style.backgroundColor;
|
|
1099
|
+
}
|
|
1100
|
+
if (style.textColor) {
|
|
1101
|
+
out.color = style.textColor;
|
|
1102
|
+
out["--bb-button-color"] = style.textColor;
|
|
1103
|
+
}
|
|
1104
|
+
if (style.borderRadius) out.borderRadius = style.borderRadius;
|
|
1105
|
+
if (style.fontSize) out.fontSize = style.fontSize;
|
|
1106
|
+
if (style.fontWeight) out.fontWeight = style.fontWeight;
|
|
1107
|
+
if (style.padding) out.padding = style.padding;
|
|
1108
|
+
if (style.border) out.border = style.border;
|
|
1109
|
+
if (style.hoverBackgroundColor) out["--bb-button-hover-bg"] = style.hoverBackgroundColor;
|
|
1110
|
+
if (style.hoverTextColor) out["--bb-button-hover-color"] = style.hoverTextColor;
|
|
1111
|
+
return out;
|
|
1112
|
+
}
|
|
1113
|
+
function handleFileDownload(event, url, name) {
|
|
1114
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
event.preventDefault();
|
|
1118
|
+
void (async () => {
|
|
1119
|
+
try {
|
|
1120
|
+
const response = await fetch(url);
|
|
1121
|
+
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
|
|
1122
|
+
const blob = await response.blob();
|
|
1123
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
1124
|
+
const anchor = document.createElement("a");
|
|
1125
|
+
anchor.href = objectUrl;
|
|
1126
|
+
anchor.download = name;
|
|
1127
|
+
document.body.appendChild(anchor);
|
|
1128
|
+
anchor.click();
|
|
1129
|
+
anchor.remove();
|
|
1130
|
+
URL.revokeObjectURL(objectUrl);
|
|
1131
|
+
} catch (e) {
|
|
1132
|
+
window.location.href = url;
|
|
1133
|
+
}
|
|
1134
|
+
})();
|
|
1135
|
+
}
|
|
1136
|
+
function renderButton(block, key, blocks) {
|
|
1137
|
+
var _a;
|
|
1138
|
+
const ButtonComp = blocks == null ? void 0 : blocks.button;
|
|
1139
|
+
if (ButtonComp) {
|
|
1140
|
+
return /* @__PURE__ */ jsx5(
|
|
1141
|
+
ButtonComp,
|
|
1142
|
+
{
|
|
1143
|
+
label: block.label,
|
|
1144
|
+
buttonType: block.buttonType,
|
|
1145
|
+
alignment: block.alignment,
|
|
1146
|
+
link: block.link,
|
|
1147
|
+
file: block.file,
|
|
1148
|
+
showFileSize: block.showFileSize,
|
|
1149
|
+
showFileIcon: block.showFileIcon,
|
|
1150
|
+
filePreview: block.filePreview,
|
|
1151
|
+
style: block.style,
|
|
1152
|
+
cssClass: block.cssClass
|
|
1153
|
+
},
|
|
1154
|
+
key
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
const style = getButtonStyle(block.style);
|
|
1158
|
+
const className = block.cssClass ? `bb-button ${block.cssClass}` : "bb-button";
|
|
1159
|
+
let control;
|
|
1160
|
+
if (block.buttonType === "file" && block.file) {
|
|
1161
|
+
const file = block.file;
|
|
1162
|
+
const icon = block.showFileIcon ? getFileIcon(file) : null;
|
|
1163
|
+
const size = block.showFileSize && typeof file.size === "number" ? formatFileSize(file.size) : null;
|
|
1164
|
+
const filePreview = block.filePreview === true;
|
|
1165
|
+
control = filePreview ? /* @__PURE__ */ jsxs4(
|
|
1166
|
+
"a",
|
|
1167
|
+
{
|
|
1168
|
+
href: file.url,
|
|
1169
|
+
target: "_blank",
|
|
1170
|
+
rel: "noopener noreferrer",
|
|
1171
|
+
"aria-label": `Preview ${file.name}`,
|
|
1172
|
+
className,
|
|
1173
|
+
style,
|
|
1174
|
+
children: [
|
|
1175
|
+
icon && /* @__PURE__ */ jsxs4("span", { className: "bb-button-icon", "aria-hidden": "true", children: [
|
|
1176
|
+
icon,
|
|
1177
|
+
" "
|
|
1178
|
+
] }),
|
|
1179
|
+
block.label,
|
|
1180
|
+
size && /* @__PURE__ */ jsxs4("span", { className: "bb-button-size", children: [
|
|
1181
|
+
" (",
|
|
1182
|
+
size,
|
|
1183
|
+
")"
|
|
1184
|
+
] })
|
|
1185
|
+
]
|
|
1186
|
+
}
|
|
1187
|
+
) : /* @__PURE__ */ jsxs4(
|
|
1188
|
+
"a",
|
|
1189
|
+
{
|
|
1190
|
+
href: file.url,
|
|
1191
|
+
download: file.name,
|
|
1192
|
+
"aria-label": `Download ${file.name}`,
|
|
1193
|
+
className,
|
|
1194
|
+
style,
|
|
1195
|
+
onClick: (event) => handleFileDownload(event, file.url, file.name),
|
|
1196
|
+
children: [
|
|
1197
|
+
icon && /* @__PURE__ */ jsxs4("span", { className: "bb-button-icon", "aria-hidden": "true", children: [
|
|
1198
|
+
icon,
|
|
1199
|
+
" "
|
|
1200
|
+
] }),
|
|
1201
|
+
block.label,
|
|
1202
|
+
size && /* @__PURE__ */ jsxs4("span", { className: "bb-button-size", children: [
|
|
1203
|
+
" (",
|
|
1204
|
+
size,
|
|
1205
|
+
")"
|
|
1206
|
+
] })
|
|
1207
|
+
]
|
|
1208
|
+
}
|
|
1209
|
+
);
|
|
1210
|
+
} else if (block.link) {
|
|
1211
|
+
const link = block.link;
|
|
1212
|
+
control = /* @__PURE__ */ jsx5(
|
|
1213
|
+
"a",
|
|
1214
|
+
{
|
|
1215
|
+
href: link.url,
|
|
1216
|
+
target: link.target,
|
|
1217
|
+
rel: link.rel,
|
|
1218
|
+
"aria-label": link.ariaLabel,
|
|
1219
|
+
className,
|
|
1220
|
+
style,
|
|
1221
|
+
children: block.label
|
|
1222
|
+
}
|
|
1223
|
+
);
|
|
1224
|
+
} else {
|
|
1225
|
+
control = /* @__PURE__ */ jsx5("span", { className, style, children: block.label });
|
|
1226
|
+
}
|
|
1227
|
+
const alignment = (_a = block.alignment) != null ? _a : "left";
|
|
1228
|
+
if (alignment === "none") {
|
|
1229
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: control }, key);
|
|
1230
|
+
}
|
|
1231
|
+
return /* @__PURE__ */ jsx5(
|
|
1232
|
+
"div",
|
|
1233
|
+
{
|
|
1234
|
+
className: "bb-button-wrapper",
|
|
1235
|
+
style: { textAlign: alignment, margin: "0.5rem 0" },
|
|
1236
|
+
children: control
|
|
1237
|
+
},
|
|
1238
|
+
key
|
|
1239
|
+
);
|
|
1240
|
+
}
|
|
1241
|
+
function BlocksRenderer({
|
|
1242
|
+
content,
|
|
1243
|
+
blocks,
|
|
1244
|
+
modifiers,
|
|
1245
|
+
codeTheme = DEFAULT_CODE_THEME,
|
|
1246
|
+
codeCopyButton = false
|
|
1247
|
+
}) {
|
|
1248
|
+
if (!content || !Array.isArray(content) || content.length === 0) {
|
|
1249
|
+
return null;
|
|
1250
|
+
}
|
|
1251
|
+
const needsButtonCss = !(blocks == null ? void 0 : blocks.button) && contentHasBlock(content, "button");
|
|
1252
|
+
const needsEmbedCss = !(blocks == null ? void 0 : blocks.embed) && contentHasBlock(content, "embed");
|
|
1253
|
+
const needsTableCss = !(blocks == null ? void 0 : blocks.table) && contentHasBlock(content, "table");
|
|
1254
|
+
const needsQuoteCss = !(blocks == null ? void 0 : blocks.quote) && contentHasBlock(content, "quote");
|
|
1255
|
+
const needsCodeCss = !(blocks == null ? void 0 : blocks.code) && contentHasBlock(content, "code");
|
|
1256
|
+
const options = { codeTheme, codeCopyButton };
|
|
1257
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1258
|
+
needsButtonCss && /* @__PURE__ */ jsx5("style", { children: BUTTON_HOVER_CSS }),
|
|
1259
|
+
needsEmbedCss && /* @__PURE__ */ jsx5("style", { children: EMBED_FRAME_CSS }),
|
|
1260
|
+
needsTableCss && /* @__PURE__ */ jsx5("style", { children: TABLE_CSS }),
|
|
1261
|
+
needsQuoteCss && /* @__PURE__ */ jsx5("style", { children: QUOTE_CSS }),
|
|
1262
|
+
needsCodeCss && /* @__PURE__ */ jsx5("style", { children: CODE_CSS }),
|
|
1263
|
+
content.map((block, index) => renderBlock(block, index, blocks, modifiers, options))
|
|
1264
|
+
] });
|
|
1265
|
+
}
|
|
1266
|
+
export {
|
|
1267
|
+
BlocksRenderer
|
|
1268
|
+
};
|
|
1269
|
+
//# sourceMappingURL=index.mjs.map
|