UNPKG

@lobehub/ui

Version:

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

202 lines (192 loc) 11.8 kB
'use client'; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var _excluded = ["ref", "children", "className", "style", "fullFeaturedCodeBlock", "onDoubleClick", "enableLatex", "enableMermaid", "enableImageGallery", "enableCustomFootnotes", "componentProps", "allowHtml", "fontSize", "headerMultiple", "marginMultiple", "showFootnotes", "variant", "reactMarkdownProps", "lineHeight", "rehypePlugins", "remarkPlugins", "remarkPluginsAhead", "components", "customRender", "citations"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } import { cva } from 'class-variance-authority'; import { memo, useCallback, useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; import { PreviewGroup } from "../Image"; import Image from "../mdx/mdxComponents/Image"; import Link from "../mdx/mdxComponents/Link"; import Section from "../mdx/mdxComponents/Section"; import Video from "../mdx/mdxComponents/Video"; import { CodeFullFeatured, CodeLite } from "./CodeBlock"; import Typography from "./Typography"; import { useStyles } from "./style"; import { addToCache, contentCache, createPlugins, escapeBrackets, escapeMhchem, fixMarkdownBold, transformCitations } from "./utils"; import { jsx as _jsx } from "react/jsx-runtime"; var Markdown = /*#__PURE__*/memo(function (_ref) { var ref = _ref.ref, children = _ref.children, className = _ref.className, style = _ref.style, fullFeaturedCodeBlock = _ref.fullFeaturedCodeBlock, onDoubleClick = _ref.onDoubleClick, _ref$enableLatex = _ref.enableLatex, enableLatex = _ref$enableLatex === void 0 ? true : _ref$enableLatex, _ref$enableMermaid = _ref.enableMermaid, enableMermaid = _ref$enableMermaid === void 0 ? true : _ref$enableMermaid, _ref$enableImageGalle = _ref.enableImageGallery, enableImageGallery = _ref$enableImageGalle === void 0 ? true : _ref$enableImageGalle, enableCustomFootnotes = _ref.enableCustomFootnotes, componentProps = _ref.componentProps, allowHtml = _ref.allowHtml, _ref$fontSize = _ref.fontSize, fontSize = _ref$fontSize === void 0 ? 14 : _ref$fontSize, _ref$headerMultiple = _ref.headerMultiple, headerMultiple = _ref$headerMultiple === void 0 ? 0.25 : _ref$headerMultiple, _ref$marginMultiple = _ref.marginMultiple, marginMultiple = _ref$marginMultiple === void 0 ? 1 : _ref$marginMultiple, showFootnotes = _ref.showFootnotes, _ref$variant = _ref.variant, variant = _ref$variant === void 0 ? 'default' : _ref$variant, reactMarkdownProps = _ref.reactMarkdownProps, _ref$lineHeight = _ref.lineHeight, lineHeight = _ref$lineHeight === void 0 ? 1.6 : _ref$lineHeight, rehypePlugins = _ref.rehypePlugins, remarkPlugins = _ref.remarkPlugins, remarkPluginsAhead = _ref.remarkPluginsAhead, _ref$components = _ref.components, components = _ref$components === void 0 ? {} : _ref$components, customRender = _ref.customRender, citations = _ref.citations, rest = _objectWithoutProperties(_ref, _excluded); var _useStyles = useStyles(), cx = _useStyles.cx, styles = _useStyles.styles; var isChatMode = variant === 'chat'; var variants = useMemo(function () { return cva(styles.root, { defaultVariants: { enableLatex: true, variant: 'default' }, /* eslint-disable sort-keys-fix/sort-keys-fix */ variants: { variant: { default: null, chat: styles.chat }, enableLatex: { true: styles.latex, false: null } } /* eslint-enable sort-keys-fix/sort-keys-fix */ }); }, [styles]); // 计算缓存键 var cacheKey = useMemo(function () { return "".concat(children, "-").concat(enableLatex, "-").concat(enableCustomFootnotes, "-").concat((citations === null || citations === void 0 ? void 0 : citations.length) || 0); }, [children, enableLatex, enableCustomFootnotes, citations === null || citations === void 0 ? void 0 : citations.length]); // 处理内容并利用缓存避免重复计算 var escapedContent = useMemo(function () { // 尝试从缓存获取 if (contentCache.has(cacheKey)) { return contentCache.get(cacheKey); } // 处理新内容 var processedContent; if (enableLatex) { var baseContent = fixMarkdownBold(escapeMhchem(escapeBrackets(children))); processedContent = enableCustomFootnotes ? transformCitations(baseContent, citations === null || citations === void 0 ? void 0 : citations.length) : baseContent; } else { processedContent = fixMarkdownBold(children); } // 缓存处理结果 addToCache(cacheKey, processedContent); return processedContent; }, [cacheKey, children, enableLatex, enableCustomFootnotes, citations === null || citations === void 0 ? void 0 : citations.length]); // 创建插件 var _useMemo = useMemo(function () { return createPlugins({ allowHtml: allowHtml, enableCustomFootnotes: enableCustomFootnotes, enableLatex: enableLatex, isChatMode: isChatMode, rehypePlugins: rehypePlugins, remarkPlugins: remarkPlugins, remarkPluginsAhead: remarkPluginsAhead }); }, [allowHtml, enableLatex, enableCustomFootnotes, isChatMode, rehypePlugins, remarkPlugins, remarkPluginsAhead]), rehypePluginsList = _useMemo.rehypePluginsList, remarkPluginsList = _useMemo.remarkPluginsList; // 使用 useCallback 优化渲染子组件 var renderLink = useCallback(function (props) { return /*#__PURE__*/_jsx(Link, _objectSpread(_objectSpread({ citations: citations }, props), componentProps === null || componentProps === void 0 ? void 0 : componentProps.a)); }, [citations, componentProps === null || componentProps === void 0 ? void 0 : componentProps.a]); var renderImage = useCallback(function (props) { return /*#__PURE__*/_jsx(Image, _objectSpread(_objectSpread({}, props), componentProps === null || componentProps === void 0 ? void 0 : componentProps.img)); }, [isChatMode, componentProps === null || componentProps === void 0 ? void 0 : componentProps.img]); var renderCodeBlock = useCallback(function (props) { return fullFeaturedCodeBlock ? /*#__PURE__*/_jsx(CodeFullFeatured, _objectSpread(_objectSpread({ enableMermaid: enableMermaid, highlight: componentProps === null || componentProps === void 0 ? void 0 : componentProps.highlight, mermaid: componentProps === null || componentProps === void 0 ? void 0 : componentProps.mermaid }, props), componentProps === null || componentProps === void 0 ? void 0 : componentProps.pre)) : /*#__PURE__*/_jsx(CodeLite, _objectSpread(_objectSpread({ enableMermaid: enableMermaid, highlight: componentProps === null || componentProps === void 0 ? void 0 : componentProps.highlight, mermaid: componentProps === null || componentProps === void 0 ? void 0 : componentProps.mermaid }, props), componentProps === null || componentProps === void 0 ? void 0 : componentProps.pre)); }, [enableMermaid, fullFeaturedCodeBlock, componentProps === null || componentProps === void 0 ? void 0 : componentProps.highlight, componentProps === null || componentProps === void 0 ? void 0 : componentProps.mermaid, componentProps === null || componentProps === void 0 ? void 0 : componentProps.pre]); var renderSection = useCallback(function (props) { return /*#__PURE__*/_jsx(Section, _objectSpread({ showCitations: showFootnotes }, props)); }, [showFootnotes]); var renderVideo = useCallback(function (props) { return /*#__PURE__*/_jsx(Video, _objectSpread(_objectSpread({}, props), componentProps === null || componentProps === void 0 ? void 0 : componentProps.video)); }, [componentProps === null || componentProps === void 0 ? void 0 : componentProps.video]); // 创建组件映射 var memoComponents = useMemo(function () { return _objectSpread({ a: renderLink, img: enableImageGallery ? renderImage : undefined, pre: renderCodeBlock, section: renderSection, video: renderVideo }, components); }, [renderLink, renderImage, renderCodeBlock, renderSection, renderVideo, enableImageGallery, components]); // 渲染默认内容 var defaultDOM = useMemo(function () { return /*#__PURE__*/_jsx(PreviewGroup, { enable: enableImageGallery, children: /*#__PURE__*/_jsx(ReactMarkdown, _objectSpread(_objectSpread({}, reactMarkdownProps), {}, { components: memoComponents, rehypePlugins: rehypePluginsList, remarkPlugins: remarkPluginsList, children: escapedContent })) }); }, [escapedContent, memoComponents, rehypePluginsList, remarkPluginsList, enableImageGallery]); // 应用自定义渲染 var markdownContent = customRender ? customRender(defaultDOM, { text: escapedContent || '' }) : defaultDOM; return /*#__PURE__*/_jsx(Typography, _objectSpread(_objectSpread({ className: cx(variants({ enableLatex: enableLatex, variant: variant }), className), "data-code-type": "markdown", fontSize: fontSize, headerMultiple: headerMultiple, lineHeight: lineHeight, marginMultiple: marginMultiple, onDoubleClick: onDoubleClick, ref: ref, style: style }, rest), {}, { children: markdownContent })); }); Markdown.displayName = 'Markdown'; export default Markdown;