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