UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

82 lines (80 loc) 2.47 kB
import { visit } from "../../node_modules/unist-util-visit/lib/index.mjs"; //#region src/Markdown/plugins/rehypeStreamAnimated.ts const BLOCK_TAGS = new Set([ "p", "h1", "h2", "h3", "h4", "h5", "h6", "li" ]); const SKIP_TAGS = new Set([ "pre", "code", "table", "svg" ]); function hasClass(node, cls) { const cn = node.properties?.className; if (Array.isArray(cn)) return cn.some((c) => String(c).includes(cls)); if (typeof cn === "string") return cn.includes(cls); return false; } const rehypeStreamAnimated = (options = {}) => { const { charDelay = 20, fadeDuration = 150, baseCharCount = 0, revealed = false, timelineElapsedMs } = options; const hasTimeline = typeof timelineElapsedMs === "number" && Number.isFinite(timelineElapsedMs); return (tree) => { let globalCharIndex = 0; const shouldSkip = (node) => { return SKIP_TAGS.has(node.tagName) || hasClass(node, "katex"); }; const wrapText = (node) => { const newChildren = []; for (const child of node.children) if (child.type === "text") for (const char of child.value) { const relativeIndex = globalCharIndex - baseCharCount; let className = "stream-char"; let delay; if (revealed) className = "stream-char stream-char-revealed"; else if (hasTimeline) { const progress = timelineElapsedMs - globalCharIndex * charDelay; if (progress >= fadeDuration) className = "stream-char stream-char-revealed"; else delay = -progress; } else if (relativeIndex >= 0) delay = relativeIndex * charDelay; else { const elapsed = -relativeIndex * charDelay; if (elapsed >= fadeDuration) className = "stream-char stream-char-revealed"; else delay = -elapsed; } const properties = { className }; if (delay !== void 0 && delay !== 0) properties.style = `animation-delay:${delay}ms`; newChildren.push({ children: [{ type: "text", value: char }], properties, tagName: "span", type: "element" }); globalCharIndex++; } else if (child.type === "element") { if (!shouldSkip(child)) wrapText(child); newChildren.push(child); } else newChildren.push(child); node.children = newChildren; }; visit(tree, "element", ((node) => { if (shouldSkip(node)) return "skip"; if (BLOCK_TAGS.has(node.tagName)) { wrapText(node); return "skip"; } })); }; }; //#endregion export { rehypeStreamAnimated }; //# sourceMappingURL=rehypeStreamAnimated.mjs.map