@lobehub/ui 5.23.5 → 5.24.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/es/Accordion/Accordion.mjs.map +1 -1
- package/es/Accordion/AccordionItem.mjs.map +1 -1
- package/es/Accordion/ArrowIcon.mjs.map +1 -1
- package/es/ActionIcon/ActionIcon.mjs.map +1 -1
- package/es/ActionIconGroup/ActionIconGroup.mjs.map +1 -1
- package/es/Alert/Alert.mjs.map +1 -1
- package/es/Avatar/Avatar.mjs.map +1 -1
- package/es/Avatar/AvatarGroup/index.mjs.map +1 -1
- package/es/Burger/Burger.mjs.map +1 -1
- package/es/Checkbox/Checkbox.mjs.map +1 -1
- package/es/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/CodeDiff/DiffPanel.mjs.map +1 -1
- package/es/CodeEditor/CodeEditor.mjs.map +1 -1
- package/es/Collapse/Collapse.mjs.map +1 -1
- package/es/ColorSwatches/ColorSwatches.mjs.map +1 -1
- package/es/ConfigProvider/index.mjs.map +1 -1
- package/es/ContextMenu/index.d.mts +2 -2
- package/es/ContextMenu/index.mjs +2 -2
- package/es/DraggablePanel/DraggablePanel.mjs.map +1 -1
- package/es/DraggablePanel/components/DraggablePanelHeader.mjs.map +1 -1
- package/es/DraggableSideNav/DraggableSideNav.mjs.map +1 -1
- package/es/Drawer/Drawer.mjs.map +1 -1
- package/es/Dropdown/Dropdown.mjs.map +1 -1
- package/es/EditableText/ControlInput.mjs.map +1 -1
- package/es/EditableText/EditableText.mjs.map +1 -1
- package/es/EditorSlashMenu/EditorSlashMenu.mjs.map +1 -1
- package/es/EditorSlashMenu/MenuItemRenderer.mjs.map +1 -1
- package/es/EmojiPicker/AvatarUploader.mjs.map +1 -1
- package/es/EmojiPicker/EmojiPicker.mjs.map +1 -1
- package/es/Empty/Empty.mjs.map +1 -1
- package/es/FileTypeIcon/FileTypeIcon.mjs.map +1 -1
- package/es/FileTypeIcon/components/FileIcon.mjs.map +1 -1
- package/es/FileTypeIcon/components/FolderIcon.mjs.map +1 -1
- package/es/FluentEmoji/FluentEmoji.mjs.map +1 -1
- package/es/Footer/Footer.mjs.map +1 -1
- package/es/Form/Form.mjs.map +1 -1
- package/es/Form/components/FormGroup.mjs.map +1 -1
- package/es/Form/components/FormSubmitFooter.mjs.map +1 -1
- package/es/Form/components/FormTitle.mjs.map +1 -1
- package/es/FormModal/FormModal.mjs.map +1 -1
- package/es/Freeze/Freeze.mjs.map +1 -1
- package/es/GroupAvatar/GroupAvatar.mjs.map +1 -1
- package/es/GuideCard/GuideCard.mjs.map +1 -1
- package/es/Header/Header.mjs.map +1 -1
- package/es/Highlighter/FullFeatured.mjs.map +1 -1
- package/es/Highlighter/Highlighter.mjs.map +1 -1
- package/es/Highlighter/LangSelect.mjs.map +1 -1
- package/es/Highlighter/SyntaxHighlighter/StreamRenderer.mjs.map +1 -1
- package/es/Highlighter/SyntaxHighlighter/style.mjs +2 -2
- package/es/Highlighter/SyntaxHighlighter/style.mjs.map +1 -1
- package/es/Hotkey/Hotkey.mjs.map +1 -1
- package/es/HotkeyInput/HotkeyInput.mjs.map +1 -1
- package/es/HtmlPreview/HtmlPreview.mjs.map +1 -1
- package/es/HtmlPreview/Iframe.mjs.map +1 -1
- package/es/Icon/Icon.mjs.map +1 -1
- package/es/Image/Image.mjs.map +1 -1
- package/es/Image/components/Toolbar.mjs.map +1 -1
- package/es/Image/components/usePreview.mjs.map +1 -1
- package/es/Image/components/usePreviewGroup.mjs.map +1 -1
- package/es/ImageSelect/ImageSelect.mjs.map +1 -1
- package/es/Layout/Layout.mjs.map +1 -1
- package/es/List/List.mjs.map +1 -1
- package/es/List/ListItem/index.mjs.map +1 -1
- package/es/Markdown/Markdown.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/MarkdownRender.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/StreamdownRender.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/style.mjs.map +1 -1
- package/es/Markdown/components/CodeBlock.mjs.map +1 -1
- package/es/Markdown/components/Footnotes.mjs.map +1 -1
- package/es/Markdown/components/MarkdownTable/index.mjs.map +1 -1
- package/es/Markdown/components/SearchResultCards/SearchResultCard.mjs.map +1 -1
- package/es/Markdown/components/SearchResultCards/index.mjs.map +1 -1
- package/es/MaterialFileTypeIcon/MaterialFileTypeIcon.mjs.map +1 -1
- package/es/Menu/Menu.mjs.map +1 -1
- package/es/Mermaid/FullFeatured.mjs.map +1 -1
- package/es/Mermaid/Mermaid.mjs.map +1 -1
- package/es/Mermaid/SyntaxMermaid/MermaidFallback.mjs +35 -0
- package/es/Mermaid/SyntaxMermaid/MermaidFallback.mjs.map +1 -0
- package/es/Mermaid/SyntaxMermaid/MermaidSvg.mjs +52 -0
- package/es/Mermaid/SyntaxMermaid/MermaidSvg.mjs.map +1 -0
- package/es/Mermaid/SyntaxMermaid/StaticMermaid.mjs +13 -42
- package/es/Mermaid/SyntaxMermaid/StaticMermaid.mjs.map +1 -1
- package/es/Mermaid/SyntaxMermaid/StreamMermaid.mjs +13 -43
- package/es/Mermaid/SyntaxMermaid/StreamMermaid.mjs.map +1 -1
- package/es/Mermaid/SyntaxMermaid/prepareInlineSvg.mjs +52 -0
- package/es/Mermaid/SyntaxMermaid/prepareInlineSvg.mjs.map +1 -0
- package/es/Mermaid/SyntaxMermaid/prepareMermaidSvg.mjs +20 -0
- package/es/Mermaid/SyntaxMermaid/prepareMermaidSvg.mjs.map +1 -0
- package/es/Mermaid/SyntaxMermaid/style.mjs +11 -0
- package/es/Mermaid/SyntaxMermaid/style.mjs.map +1 -1
- package/es/Mermaid/const.mjs +10 -31
- package/es/Mermaid/const.mjs.map +1 -1
- package/es/Mermaid/index.d.mts +2 -1
- package/es/Mermaid/index.mjs +2 -1
- package/es/Mermaid/type.d.mts +2 -2
- package/es/Modal/Modal.mjs.map +1 -1
- package/es/Modal/ModalStackItem.mjs.map +1 -1
- package/es/Modal/RawModalStackItem.mjs.map +1 -1
- package/es/Modal/imperative.mjs.map +1 -1
- package/es/Modal/style.mjs.map +1 -1
- package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs.map +1 -1
- package/es/ScrollShadow/ScrollShadow.mjs.map +1 -1
- package/es/SearchBar/SearchBar.mjs.map +1 -1
- package/es/SideNav/SideNav.mjs.map +1 -1
- package/es/Skeleton/Skeleton.mjs.map +1 -1
- package/es/Skeleton/SkeletonParagraph.mjs.map +1 -1
- package/es/Skeleton/SkeletonTags.mjs.map +1 -1
- package/es/SliderWithInput/SliderWithInput.mjs.map +1 -1
- package/es/Snippet/Snippet.mjs.map +1 -1
- package/es/SortableList/SortableList.mjs.map +1 -1
- package/es/SortableList/components/SortableItem.mjs.map +1 -1
- package/es/Text/Text.mjs.map +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs.map +1 -1
- package/es/ThemeSwitch/ThemeSwitch.mjs.map +1 -1
- package/es/Toc/Toc.mjs.map +1 -1
- package/es/Toc/TocMobile.mjs.map +1 -1
- package/es/Video/index.mjs.map +1 -1
- package/es/awesome/AuroraBackground/AuroraBackground.mjs.map +1 -1
- package/es/awesome/Features/FeatureItem.mjs.map +1 -1
- package/es/awesome/Giscus/Giscus.mjs.map +1 -1
- package/es/awesome/GradientButton/GradientButton.mjs.map +1 -1
- package/es/awesome/GridBackground/GridBackground.mjs.map +1 -1
- package/es/awesome/GridBackground/GridShowcase.mjs.map +1 -1
- package/es/awesome/GridBackground/components/Grid.mjs.map +1 -1
- package/es/awesome/Hero/Hero.mjs.map +1 -1
- package/es/awesome/Spline/ParentSize.mjs.map +1 -1
- package/es/awesome/Spline/Spine.mjs.map +1 -1
- package/es/awesome/SpotlightCard/SpotlightCard.mjs.map +1 -1
- package/es/awesome/SpotlightCard/SpotlightCardItem.mjs.map +1 -1
- package/es/awesome/TypewriterEffect/TypewriterEffect.mjs.map +1 -1
- package/es/base-ui/AutoComplete/AutoComplete.mjs.map +1 -1
- package/es/base-ui/Button/Button.mjs.map +1 -1
- package/es/base-ui/Button/SplitButton.mjs.map +1 -1
- package/es/base-ui/Checkbox/Checkbox.mjs.map +1 -1
- package/es/base-ui/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/base-ui/ContextMenu/ContextMenuHost.mjs.map +1 -1
- package/es/base-ui/ContextMenu/imperative.d.mts +2 -2
- package/es/base-ui/ContextMenu/index.d.mts +2 -2
- package/es/base-ui/ContextMenu/renderItems.mjs.map +1 -1
- package/es/base-ui/ContextMenu/store.d.mts +13 -1
- package/es/base-ui/ContextMenu/store.mjs +29 -4
- package/es/base-ui/ContextMenu/store.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/DropdownMenu.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/atoms.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/renderItems.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/sharedStyle.mjs +3 -0
- package/es/base-ui/DropdownMenu/sharedStyle.mjs.map +1 -1
- package/es/base-ui/FloatingPanel/FloatingPanel.mjs.map +1 -1
- package/es/base-ui/FloatingSheet/FloatingSheet.mjs.map +1 -1
- package/es/base-ui/FloatingSheet/FloatingSheetHeader.mjs.map +1 -1
- package/es/base-ui/Form/Form.mjs.map +1 -1
- package/es/base-ui/Form/components/FormField.mjs.map +1 -1
- package/es/base-ui/Form/components/FormGroup.mjs.map +1 -1
- package/es/base-ui/Form/components/FormSubmitFooter.mjs.map +1 -1
- package/es/base-ui/Form/components/FormTitle.mjs.map +1 -1
- package/es/base-ui/Input/Input.mjs.map +1 -1
- package/es/base-ui/Input/InputNumber.mjs.map +1 -1
- package/es/base-ui/Input/InputOTP.mjs.map +1 -1
- package/es/base-ui/Input/InputPassword.mjs.map +1 -1
- package/es/base-ui/Input/TextArea.mjs.map +1 -1
- package/es/base-ui/Input/style.d.mts +1 -1
- package/es/base-ui/Modal/Modal.mjs.map +1 -1
- package/es/base-ui/Modal/atoms.mjs.map +1 -1
- package/es/base-ui/Modal/imperative.mjs.map +1 -1
- package/es/base-ui/Popover/ArrowIcon.mjs.map +1 -1
- package/es/base-ui/Popover/PopoverGroup.mjs.map +1 -1
- package/es/base-ui/Popover/PopoverStandalone.mjs.map +1 -1
- package/es/base-ui/Popover/atoms.mjs.map +1 -1
- package/es/base-ui/Radio/Radio.mjs.map +1 -1
- package/es/base-ui/Radio/RadioGroup.mjs.map +1 -1
- package/es/base-ui/ScrollArea/ScrollArea.mjs.map +1 -1
- package/es/base-ui/Segmented/Segmented.mjs.map +1 -1
- package/es/base-ui/Select/Select.mjs.map +1 -1
- package/es/base-ui/Select/parts.mjs.map +1 -1
- package/es/base-ui/Select/renderOptions.mjs.map +1 -1
- package/es/base-ui/Slider/Slider.mjs.map +1 -1
- package/es/base-ui/Slider/SliderWithInput.mjs.map +1 -1
- package/es/base-ui/SubmenuArrowIcon.mjs.map +1 -1
- package/es/base-ui/Switch/Switch.mjs.map +1 -1
- package/es/base-ui/Switch/atoms.d.mts +3 -3
- package/es/base-ui/Switch/atoms.mjs +99 -50
- package/es/base-ui/Switch/atoms.mjs.map +1 -1
- package/es/base-ui/Switch/style.mjs +44 -1
- package/es/base-ui/Switch/style.mjs.map +1 -1
- package/es/base-ui/Switch/type.d.mts +3 -7
- package/es/base-ui/Tabs/Tabs.mjs.map +1 -1
- package/es/base-ui/Tabs/atoms.mjs.map +1 -1
- package/es/base-ui/Toast/Toast.mjs.map +1 -1
- package/es/base-ui/Toast/imperative.mjs.map +1 -1
- package/es/base-ui/Tooltip/ArrowIcon.mjs.map +1 -1
- package/es/base-ui/Tooltip/TooltipGroup.mjs.map +1 -1
- package/es/base-ui/Tooltip/TooltipStandalone.mjs.map +1 -1
- package/es/base-ui/index.d.mts +2 -2
- package/es/base-ui/index.mjs +2 -2
- package/es/brand/LobeChat/index.mjs.map +1 -1
- package/es/brand/LobeChatText/index.mjs.map +1 -1
- package/es/brand/LobeHub/index.mjs.map +1 -1
- package/es/brand/LobeHubText/index.mjs.map +1 -1
- package/es/brand/LogoThree/Loading.mjs.map +1 -1
- package/es/brand/LogoThree/LogoSpline.mjs.map +1 -1
- package/es/brand/LogoThree/index.mjs.map +1 -1
- package/es/brand/components/Divider.mjs.map +1 -1
- package/es/chat/BackBottom/BackBottom.mjs.map +1 -1
- package/es/chat/ChatHeader/ChatHeader.mjs.map +1 -1
- package/es/chat/ChatHeader/ChatHeaderTitle.mjs.map +1 -1
- package/es/chat/ChatInputArea/ChatInputArea.mjs.map +1 -1
- package/es/chat/ChatInputArea/components/ChatInputActionBar.mjs.map +1 -1
- package/es/chat/ChatInputArea/components/ChatSendButton.mjs.map +1 -1
- package/es/chat/ChatItem/ChatItem.mjs.map +1 -1
- package/es/chat/ChatItem/components/Actions.mjs.map +1 -1
- package/es/chat/ChatItem/components/Avatar.mjs.map +1 -1
- package/es/chat/ChatItem/components/ErrorContent.mjs.map +1 -1
- package/es/chat/ChatItem/components/Loading.mjs.map +1 -1
- package/es/chat/ChatItem/components/MessageContent.mjs.map +1 -1
- package/es/chat/ChatItem/components/Title.mjs.map +1 -1
- package/es/chat/ChatList/ChatList.mjs.map +1 -1
- package/es/chat/ChatList/components/HistoryDivider.mjs.map +1 -1
- package/es/chat/EditableMessage/EditableMessage.mjs.map +1 -1
- package/es/chat/EditableMessageList/EditableMessageList.mjs.map +1 -1
- package/es/chat/LoadingDots/LoadingDots.mjs.map +1 -1
- package/es/chat/MessageInput/MessageInput.mjs.map +1 -1
- package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
- package/es/color/ColorScales/ScaleRow.mjs.map +1 -1
- package/es/color/ColorScales/index.mjs.map +1 -1
- package/es/color/CssVar/ScaleRow.mjs.map +1 -1
- package/es/color/CssVar/VarRow.mjs.map +1 -1
- package/es/color/CssVar/index.mjs.map +1 -1
- package/es/hooks/useMarkdown/latex.mjs.map +1 -1
- package/es/hooks/useMarkdown/useMarkdownContent.mjs.map +1 -1
- package/es/hooks/useMermaid.mjs +80 -116
- package/es/hooks/useMermaid.mjs.map +1 -1
- package/es/hooks/useMermaidCdn.d.mts +10 -0
- package/es/hooks/useMermaidCdn.mjs +97 -0
- package/es/hooks/useMermaidCdn.mjs.map +1 -0
- package/es/hooks/useStreamMermaid.mjs +19 -70
- package/es/hooks/useStreamMermaid.mjs.map +1 -1
- package/es/icons/Auth0/components/Mono.mjs.map +1 -1
- package/es/icons/Authelia/components/Color.mjs.map +1 -1
- package/es/icons/Authelia/components/Mono.mjs.map +1 -1
- package/es/icons/Authentik/components/Color.mjs.map +1 -1
- package/es/icons/Authentik/components/Mono.mjs.map +1 -1
- package/es/icons/Casdoor/components/Color.mjs.map +1 -1
- package/es/icons/Casdoor/components/Mono.mjs.map +1 -1
- package/es/icons/Clerk/components/Color.mjs.map +1 -1
- package/es/icons/Clerk/components/Mono.mjs.map +1 -1
- package/es/icons/DingTalk/components/Color.mjs.map +1 -1
- package/es/icons/DingTalk/components/Mono.mjs.map +1 -1
- package/es/icons/Discord/components/Color.mjs.map +1 -1
- package/es/icons/Discord/components/Mono.mjs.map +1 -1
- package/es/icons/GoogleChat/components/Color.mjs.map +1 -1
- package/es/icons/GoogleChat/components/Mono.mjs.map +1 -1
- package/es/icons/IMessage/components/Color.mjs.map +1 -1
- package/es/icons/IMessage/components/Inner.mjs.map +1 -1
- package/es/icons/IMessage/components/Mono.mjs.map +1 -1
- package/es/icons/Lark/components/Color.mjs.map +1 -1
- package/es/icons/Lark/components/Mono.mjs.map +1 -1
- package/es/icons/Line/components/Color.mjs.map +1 -1
- package/es/icons/Line/components/Mono.mjs.map +1 -1
- package/es/icons/Logto/components/Color.mjs.map +1 -1
- package/es/icons/Logto/components/Mono.mjs.map +1 -1
- package/es/icons/MicrosoftEntra/components/Color.mjs.map +1 -1
- package/es/icons/MicrosoftEntra/components/Mono.mjs.map +1 -1
- package/es/icons/MicrosoftTeams/components/Color.mjs.map +1 -1
- package/es/icons/MicrosoftTeams/components/Mono.mjs.map +1 -1
- package/es/icons/NextAuth/components/Color.mjs.map +1 -1
- package/es/icons/NextAuth/components/Mono.mjs.map +1 -1
- package/es/icons/QQ/components/Color.mjs.map +1 -1
- package/es/icons/QQ/components/Mono.mjs.map +1 -1
- package/es/icons/Slack/components/Color.mjs.map +1 -1
- package/es/icons/Slack/components/Mono.mjs.map +1 -1
- package/es/icons/Telegram/components/Color.mjs.map +1 -1
- package/es/icons/Telegram/components/Inner.mjs.map +1 -1
- package/es/icons/Telegram/components/Mono.mjs.map +1 -1
- package/es/icons/WeChat/components/Color.mjs.map +1 -1
- package/es/icons/WeChat/components/Mono.mjs.map +1 -1
- package/es/icons/WhatsApp/components/Color.mjs.map +1 -1
- package/es/icons/WhatsApp/components/Mono.mjs.map +1 -1
- package/es/icons/Zitadel/components/Color.mjs.map +1 -1
- package/es/icons/Zitadel/components/Mono.mjs.map +1 -1
- package/es/index.d.mts +2 -2
- package/es/index.mjs +2 -2
- package/es/mdx/Callout/index.mjs.map +1 -1
- package/es/mdx/Cards/Card.mjs.map +1 -1
- package/es/mdx/FileTree/File.mjs.map +1 -1
- package/es/mdx/FileTree/Folder.mjs.map +1 -1
- package/es/mdx/Mdx/index.mjs.map +1 -1
- package/es/mdx/Tabs/Tab.mjs.map +1 -1
- package/es/mdx/Tabs/index.mjs.map +1 -1
- package/es/mdx/mdxComponents/Citation/PopoverPanel.mjs.map +1 -1
- package/es/mdx/mdxComponents/Citation/index.mjs.map +1 -1
- package/es/mdx/mdxComponents/CodeBlock.mjs.map +1 -1
- package/es/mdx/mdxComponents/Link.mjs.map +1 -1
- package/es/mobile/ChatHeader/ChatHeader.mjs.map +1 -1
- package/es/mobile/ChatHeader/ChatHeaderTitle.mjs.map +1 -1
- package/es/mobile/ChatInputArea/ChatInputArea.mjs.map +1 -1
- package/es/mobile/TabBar/TabBar.mjs.map +1 -1
- package/es/storybook/StoryBook/index.mjs.map +1 -1
- package/package.json +3 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StreamdownRender.mjs","names":[],"sources":["../../../src/Markdown/SyntaxMarkdown/StreamdownRender.tsx"],"sourcesContent":["'use client';\n\nimport { marked } from 'marked';\nimport {\n memo,\n Profiler,\n type ProfilerOnRenderCallback,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from 'react';\nimport { type Options } from 'react-markdown';\nimport remend from 'remend';\nimport type { Pluggable, PluggableList } from 'unified';\n\nimport {\n useMarkdownComponents,\n useMarkdownContent,\n useMarkdownRehypePlugins,\n useMarkdownRemarkPlugins,\n} from '@/hooks/useMarkdown';\nimport { useStableValue } from '@/hooks/useStableValue';\nimport { useMarkdownContext } from '@/Markdown/components/MarkdownProvider';\nimport {\n rehypeStreamAnimated,\n type StreamAnimatedRuntime,\n} from '@/Markdown/plugins/rehypeStreamAnimated';\nimport { useStreamdownProfiler } from '@/Markdown/streamProfiler';\nimport { type StreamAnimationGranularity } from '@/Markdown/type';\nimport { getNow } from '@/utils/getNow';\nimport { isDeepEqual } from '@/utils/isDeepEqual';\n\nimport { CachedMarkdown } from './CachedMarkdown';\nimport { type BlockAnimationMeta, resolveBlockAnimationMeta } from './streamAnimationMeta';\nimport { STREAM_FADE_DURATION, styles } from './style';\nimport { countChars, useSmoothStreamContent } from './useSmoothStreamContent';\nimport { type BlockInfo, type BlockState, useStreamQueue } from './useStreamQueue';\n\nconst isSamePlugin = (prevPlugin: Pluggable, nextPlugin: Pluggable): boolean => {\n const prevTuple = Array.isArray(prevPlugin) ? prevPlugin : [prevPlugin];\n const nextTuple = Array.isArray(nextPlugin) ? nextPlugin : [nextPlugin];\n\n if (prevTuple.length !== nextTuple.length) return false;\n if (prevTuple[0] !== nextTuple[0]) return false;\n\n return isDeepEqual(prevTuple.slice(1), nextTuple.slice(1));\n};\n\nconst isSamePlugins = (\n prevPlugins?: PluggableList | null,\n nextPlugins?: PluggableList | null,\n): boolean => {\n if (prevPlugins === nextPlugins) return true;\n if (!prevPlugins || !nextPlugins) return !prevPlugins && !nextPlugins;\n if (prevPlugins.length !== nextPlugins.length) return false;\n\n for (let i = 0; i < prevPlugins.length; i++) {\n if (!isSamePlugin(prevPlugins[i], nextPlugins[i])) return false;\n }\n\n return true;\n};\n\nconst useStablePlugins = (plugins: PluggableList): PluggableList => {\n const stableRef = useRef<PluggableList>(plugins);\n\n if (!isSamePlugins(stableRef.current, plugins)) {\n stableRef.current = plugins;\n }\n\n return stableRef.current;\n};\n\nconst StreamdownBlock = memo<Options>(\n ({ children, ...rest }) => {\n return <CachedMarkdown {...rest}>{children}</CachedMarkdown>;\n },\n (prevProps, nextProps) =>\n prevProps.children === nextProps.children &&\n prevProps.components === nextProps.components &&\n isSamePlugins(prevProps.rehypePlugins, nextProps.rehypePlugins) &&\n isSamePlugins(prevProps.remarkPlugins, nextProps.remarkPlugins),\n);\n\nStreamdownBlock.displayName = 'StreamdownBlock';\n\ninterface BlockRuntime extends StreamAnimatedRuntime {\n charCount: number;\n charDelay?: number;\n rawLength: number;\n settled: boolean;\n}\n\ninterface BlockPluginsCacheEntry {\n base: PluggableList;\n granularity: StreamAnimationGranularity;\n value: PluggableList;\n}\n\ninterface UpdateBlockAnimationArgs {\n blocks: BlockInfo[];\n charDelay: number;\n getBlockState: (index: number) => BlockState;\n pluginsCache: Map<number, BlockPluginsCacheEntry>;\n renderNow: number;\n revealClock: { lastTs: number };\n runtimes: Map<number, BlockRuntime>;\n}\n\nconst MIN_STREAM_CHAR_PACE_MS = 2;\nconst MAX_REVEAL_GAP_MS = 160;\n\n// Runs in the render phase: extends each visible block's birth timeline in\n// place and resolves its animation meta in one pass. Mutations are\n// idempotent for a given block content/length, so discarded or StrictMode\n// double renders re-derive the same state.\nconst updateBlockAnimation = ({\n blocks,\n charDelay,\n getBlockState,\n pluginsCache,\n renderNow,\n revealClock,\n runtimes,\n}: UpdateBlockAnimationArgs): Map<number, BlockAnimationMeta> => {\n const blockAnimationMeta = new Map<number, BlockAnimationMeta>();\n const alive = new Set<number>();\n let revealedNewChars = false;\n\n for (const [index, block] of blocks.entries()) {\n alive.add(block.startOffset);\n\n // Queued blocks are not rendered. Defer birth assignment so that\n // when the block later transitions to animating/streaming, its\n // chars start fading from that moment instead of having already\n // \"aged out\" of the fade window.\n const state = getBlockState(index);\n if (state === 'queued') continue;\n\n let runtime = runtimes.get(block.startOffset);\n if (!runtime) {\n runtime = { births: [], charCount: 0, rawLength: -1, settled: false, styles: [] };\n runtimes.set(block.startOffset, runtime);\n }\n\n if (runtime.rawLength !== block.content.length) {\n runtime.charCount = countChars(block.content);\n runtime.rawLength = block.content.length;\n }\n\n const blockCharCount = runtime.charCount;\n const births = runtime.births;\n\n if (births.length > blockCharCount) {\n // Block content shrunk (stream restart or upstream rewrite).\n births.length = blockCharCount;\n runtime.styles.length = blockCharCount;\n }\n\n if (births.length < blockCharCount) {\n // Chain each new char monotonically after the previous one so fades\n // never race out of order. Cap how far the fade queue can run ahead\n // of renderNow to prevent stream-faster-than-fade producing seconds\n // of invisible backlog at the tail.\n //\n // The streaming tail paces its stagger from the observed reveal-commit\n // gap instead of the queue's fixed charDelay: a commit's chars are\n // spread to land exactly until the next commit arrives, so the flow\n // stays per-char continuous no matter how far apart the throttled\n // commits are.\n const newChars = blockCharCount - births.length;\n let pace = charDelay;\n let cap = renderNow + STREAM_FADE_DURATION;\n if (state === 'streaming') {\n revealedNewChars = true;\n const gapMs = Math.min(Math.max(renderNow - revealClock.lastTs, 16), MAX_REVEAL_GAP_MS);\n pace = Math.min(charDelay, Math.max(gapMs / newChars, MIN_STREAM_CHAR_PACE_MS));\n cap = renderNow + gapMs + STREAM_FADE_DURATION;\n }\n for (let i = births.length; i < blockCharCount; i++) {\n const prevBirth = i > 0 ? births[i - 1] : renderNow - pace;\n const chained = prevBirth + pace;\n births.push(Math.min(cap, Math.max(chained, renderNow)));\n }\n }\n\n let meta: BlockAnimationMeta;\n if (runtime.settled) {\n // Settled is monotone: a revealed block's births are frozen, so once\n // its last fade completed it stays settled until the runtime is\n // pruned by a stream restart.\n meta = { charDelay: runtime.charDelay ?? charDelay, settled: true };\n } else {\n const lastBirthTs = births.length > 0 ? (births.at(-1) ?? renderNow) : renderNow;\n meta = resolveBlockAnimationMeta({\n currentCharDelay: charDelay,\n fadeDuration: STREAM_FADE_DURATION,\n lastElapsedMs: renderNow - lastBirthTs,\n previousCharDelay: runtime.charDelay,\n state,\n });\n runtime.settled = meta.settled;\n }\n runtime.charDelay = meta.charDelay;\n\n blockAnimationMeta.set(block.startOffset, meta);\n }\n\n if (revealedNewChars) {\n revealClock.lastTs = renderNow;\n }\n\n for (const key of runtimes.keys()) {\n if (!alive.has(key)) {\n runtimes.delete(key);\n pluginsCache.delete(key);\n }\n }\n\n return blockAnimationMeta;\n};\n\ninterface StreamdownBlocksProps {\n content: string;\n markdownOptions: Omit<Options, 'children'>;\n}\n\nconst StreamdownBlocks = memo<StreamdownBlocksProps>(\n ({ content: smoothedContent, markdownOptions: rest }) => {\n const { streamAnimationGranularity = 'char' } = useMarkdownContext();\n const profiler = useStreamdownProfiler();\n const components = useMarkdownComponents();\n const baseRehypePlugins = useStablePlugins(useMarkdownRehypePlugins());\n const remarkPlugins = useStablePlugins(useMarkdownRemarkPlugins());\n const generatedId = useId();\n\n const processedContentResult = useMemo(() => {\n const start = profiler ? getNow() : 0;\n const value = remend(smoothedContent);\n\n return {\n durationMs: profiler ? getNow() - start : 0,\n value,\n };\n }, [profiler, smoothedContent]);\n const processedContent = processedContentResult.value;\n\n const blocksResult = useMemo(() => {\n const start = profiler ? getNow() : 0;\n const tokens = marked.lexer(processedContent);\n let offset = 0;\n\n const value = tokens.map((token) => {\n const block = { content: token.raw, startOffset: offset };\n offset += token.raw.length;\n return block;\n });\n\n return {\n durationMs: profiler ? getNow() - start : 0,\n value,\n };\n }, [processedContent, profiler]);\n const blocks: BlockInfo[] = blocksResult.value;\n\n const { getBlockState, charDelay } = useStreamQueue(blocks);\n const blockRuntimesRef = useRef<Map<number, BlockRuntime>>(new Map());\n const blockPluginsRef = useRef<Map<number, BlockPluginsCacheEntry>>(new Map());\n const revealClockRef = useRef<{ lastTs: number }>({ lastTs: 0 });\n\n const renderNow = getNow();\n\n const animationStart = profiler ? getNow() : 0;\n const blockAnimationMeta = updateBlockAnimation({\n blocks,\n charDelay,\n getBlockState,\n pluginsCache: blockPluginsRef.current,\n renderNow,\n revealClock: revealClockRef.current,\n runtimes: blockRuntimesRef.current,\n });\n const blockAnimationDurationMs = profiler ? getNow() - animationStart : 0;\n\n useEffect(() => {\n if (!profiler) return;\n\n profiler.recordCalculation({\n durationMs: processedContentResult.durationMs,\n name: 'content-normalize',\n textLength: processedContent.length,\n });\n }, [processedContent.length, processedContentResult.durationMs, profiler]);\n\n useEffect(() => {\n if (!profiler) return;\n\n profiler.recordCalculation({\n durationMs: blocksResult.durationMs,\n itemCount: blocks.length,\n name: 'block-lex',\n textLength: processedContent.length,\n });\n }, [blocks.length, blocksResult.durationMs, processedContent.length, profiler]);\n\n useEffect(() => {\n if (!profiler) return;\n\n profiler.recordCalculation({\n durationMs: blockAnimationDurationMs,\n itemCount: blocks.length,\n name: 'block-births',\n textLength: processedContent.length,\n });\n }, [blockAnimationDurationMs, blocks.length, processedContent.length, profiler]);\n\n const resolveBlockPlugins = (startOffset: number, settled: boolean): PluggableList => {\n if (settled) return baseRehypePlugins;\n\n const cache = blockPluginsRef.current;\n const entry = cache.get(startOffset);\n if (\n entry &&\n entry.base === baseRehypePlugins &&\n entry.granularity === streamAnimationGranularity\n ) {\n return entry.value;\n }\n\n const runtime = blockRuntimesRef.current.get(startOffset);\n const value: PluggableList = [\n ...baseRehypePlugins,\n [\n rehypeStreamAnimated,\n {\n fadeDuration: STREAM_FADE_DURATION,\n granularity: streamAnimationGranularity,\n runtime,\n },\n ],\n ];\n cache.set(startOffset, {\n base: baseRehypePlugins,\n granularity: streamAnimationGranularity,\n value,\n });\n return value;\n };\n\n const handleRootRender = useCallback<ProfilerOnRenderCallback>(\n (_, phase, actualDuration, baseDuration) => {\n profiler?.recordRootCommit({\n actualDuration,\n baseDuration,\n blockCount: blocks.length,\n phase,\n textLength: processedContent.length,\n });\n },\n [blocks.length, processedContent.length, profiler],\n );\n\n const handleBlockRender = useCallback<ProfilerOnRenderCallback>(\n (id, phase, actualDuration, baseDuration) => {\n if (!profiler) return;\n\n const [, indexText, offsetText] = id.split(':');\n const blockIndex = Number(indexText);\n\n if (!Number.isFinite(blockIndex)) return;\n\n const block = blocks[blockIndex];\n if (!block) return;\n\n profiler.recordBlockCommit({\n actualDuration,\n baseDuration,\n blockChars: countChars(block.content),\n blockIndex,\n blockKey: offsetText ?? String(block.startOffset),\n phase,\n state: getBlockState(blockIndex),\n });\n },\n [blocks, getBlockState, profiler],\n );\n\n const content = (\n <div className={styles.animated}>\n {blocks.map((block, index) => {\n const animationMeta = blockAnimationMeta.get(block.startOffset);\n if (!animationMeta) return null;\n\n const plugins = resolveBlockPlugins(block.startOffset, animationMeta.settled);\n const key = `${generatedId}-${block.startOffset}`;\n\n if (!profiler) {\n return (\n <StreamdownBlock\n {...rest}\n components={components}\n key={key}\n rehypePlugins={plugins}\n remarkPlugins={remarkPlugins}\n >\n {block.content}\n </StreamdownBlock>\n );\n }\n\n return (\n <Profiler\n id={`streamdown-block:${index}:${block.startOffset}`}\n key={key}\n onRender={handleBlockRender}\n >\n <StreamdownBlock\n {...rest}\n components={components}\n rehypePlugins={plugins}\n remarkPlugins={remarkPlugins}\n >\n {block.content}\n </StreamdownBlock>\n </Profiler>\n );\n })}\n </div>\n );\n\n if (!profiler) return content;\n\n return (\n <Profiler id={'streamdown-root'} onRender={handleRootRender}>\n {content}\n </Profiler>\n );\n },\n);\n\nStreamdownBlocks.displayName = 'StreamdownBlocks';\n\n// The outer component absorbs the upstream per-chunk prop churn: every\n// streamed chunk re-renders it, but it only feeds the smoother and renders\n// a memoized child keyed on the smoother's output — so the expensive block\n// pipeline runs per reveal commit, not per chunk AND per commit.\nexport const StreamdownRender = memo<Options>(({ children, ...rest }) => {\n const { streamSmoothingPreset = 'balanced' } = useMarkdownContext();\n const escapedContent = useMarkdownContent(children || '');\n const smoothedContent = useSmoothStreamContent(\n typeof escapedContent === 'string' ? escapedContent : '',\n { preset: streamSmoothingPreset },\n );\n const markdownOptions = useStableValue(rest);\n\n return <StreamdownBlocks content={smoothedContent} markdownOptions={markdownOptions} />;\n});\n\nStreamdownRender.displayName = 'StreamdownRender';\n\nexport default StreamdownRender;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StreamdownRender.mjs","names":[],"sources":["../../../src/Markdown/SyntaxMarkdown/StreamdownRender.tsx"],"sourcesContent":["'use client';\n\nimport { marked } from 'marked';\nimport {\n memo,\n Profiler,\n type ProfilerOnRenderCallback,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from 'react';\nimport { type Options } from 'react-markdown';\nimport remend from 'remend';\nimport type { Pluggable, PluggableList } from 'unified';\n\nimport {\n useMarkdownComponents,\n useMarkdownContent,\n useMarkdownRehypePlugins,\n useMarkdownRemarkPlugins,\n} from '@/hooks/useMarkdown';\nimport { useStableValue } from '@/hooks/useStableValue';\nimport { useMarkdownContext } from '@/Markdown/components/MarkdownProvider';\nimport {\n rehypeStreamAnimated,\n type StreamAnimatedRuntime,\n} from '@/Markdown/plugins/rehypeStreamAnimated';\nimport { useStreamdownProfiler } from '@/Markdown/streamProfiler';\nimport { type StreamAnimationGranularity } from '@/Markdown/type';\nimport { getNow } from '@/utils/getNow';\nimport { isDeepEqual } from '@/utils/isDeepEqual';\n\nimport { CachedMarkdown } from './CachedMarkdown';\nimport { type BlockAnimationMeta, resolveBlockAnimationMeta } from './streamAnimationMeta';\nimport { STREAM_FADE_DURATION, styles } from './style';\nimport { countChars, useSmoothStreamContent } from './useSmoothStreamContent';\nimport { type BlockInfo, type BlockState, useStreamQueue } from './useStreamQueue';\n\nconst isSamePlugin = (prevPlugin: Pluggable, nextPlugin: Pluggable): boolean => {\n const prevTuple = Array.isArray(prevPlugin) ? prevPlugin : [prevPlugin];\n const nextTuple = Array.isArray(nextPlugin) ? nextPlugin : [nextPlugin];\n\n if (prevTuple.length !== nextTuple.length) return false;\n if (prevTuple[0] !== nextTuple[0]) return false;\n\n return isDeepEqual(prevTuple.slice(1), nextTuple.slice(1));\n};\n\nconst isSamePlugins = (\n prevPlugins?: PluggableList | null,\n nextPlugins?: PluggableList | null,\n): boolean => {\n if (prevPlugins === nextPlugins) return true;\n if (!prevPlugins || !nextPlugins) return !prevPlugins && !nextPlugins;\n if (prevPlugins.length !== nextPlugins.length) return false;\n\n for (let i = 0; i < prevPlugins.length; i++) {\n if (!isSamePlugin(prevPlugins[i], nextPlugins[i])) return false;\n }\n\n return true;\n};\n\nconst useStablePlugins = (plugins: PluggableList): PluggableList => {\n const stableRef = useRef<PluggableList>(plugins);\n\n if (!isSamePlugins(stableRef.current, plugins)) {\n stableRef.current = plugins;\n }\n\n return stableRef.current;\n};\n\nconst StreamdownBlock = memo<Options>(\n ({ children, ...rest }) => {\n return <CachedMarkdown {...rest}>{children}</CachedMarkdown>;\n },\n (prevProps, nextProps) =>\n prevProps.children === nextProps.children &&\n prevProps.components === nextProps.components &&\n isSamePlugins(prevProps.rehypePlugins, nextProps.rehypePlugins) &&\n isSamePlugins(prevProps.remarkPlugins, nextProps.remarkPlugins),\n);\n\nStreamdownBlock.displayName = 'StreamdownBlock';\n\ninterface BlockRuntime extends StreamAnimatedRuntime {\n charCount: number;\n charDelay?: number;\n rawLength: number;\n settled: boolean;\n}\n\ninterface BlockPluginsCacheEntry {\n base: PluggableList;\n granularity: StreamAnimationGranularity;\n value: PluggableList;\n}\n\ninterface UpdateBlockAnimationArgs {\n blocks: BlockInfo[];\n charDelay: number;\n getBlockState: (index: number) => BlockState;\n pluginsCache: Map<number, BlockPluginsCacheEntry>;\n renderNow: number;\n revealClock: { lastTs: number };\n runtimes: Map<number, BlockRuntime>;\n}\n\nconst MIN_STREAM_CHAR_PACE_MS = 2;\nconst MAX_REVEAL_GAP_MS = 160;\n\n// Runs in the render phase: extends each visible block's birth timeline in\n// place and resolves its animation meta in one pass. Mutations are\n// idempotent for a given block content/length, so discarded or StrictMode\n// double renders re-derive the same state.\nconst updateBlockAnimation = ({\n blocks,\n charDelay,\n getBlockState,\n pluginsCache,\n renderNow,\n revealClock,\n runtimes,\n}: UpdateBlockAnimationArgs): Map<number, BlockAnimationMeta> => {\n const blockAnimationMeta = new Map<number, BlockAnimationMeta>();\n const alive = new Set<number>();\n let revealedNewChars = false;\n\n for (const [index, block] of blocks.entries()) {\n alive.add(block.startOffset);\n\n // Queued blocks are not rendered. Defer birth assignment so that\n // when the block later transitions to animating/streaming, its\n // chars start fading from that moment instead of having already\n // \"aged out\" of the fade window.\n const state = getBlockState(index);\n if (state === 'queued') continue;\n\n let runtime = runtimes.get(block.startOffset);\n if (!runtime) {\n runtime = { births: [], charCount: 0, rawLength: -1, settled: false, styles: [] };\n runtimes.set(block.startOffset, runtime);\n }\n\n if (runtime.rawLength !== block.content.length) {\n runtime.charCount = countChars(block.content);\n runtime.rawLength = block.content.length;\n }\n\n const blockCharCount = runtime.charCount;\n const births = runtime.births;\n\n if (births.length > blockCharCount) {\n // Block content shrunk (stream restart or upstream rewrite).\n births.length = blockCharCount;\n runtime.styles.length = blockCharCount;\n }\n\n if (births.length < blockCharCount) {\n // Chain each new char monotonically after the previous one so fades\n // never race out of order. Cap how far the fade queue can run ahead\n // of renderNow to prevent stream-faster-than-fade producing seconds\n // of invisible backlog at the tail.\n //\n // The streaming tail paces its stagger from the observed reveal-commit\n // gap instead of the queue's fixed charDelay: a commit's chars are\n // spread to land exactly until the next commit arrives, so the flow\n // stays per-char continuous no matter how far apart the throttled\n // commits are.\n const newChars = blockCharCount - births.length;\n let pace = charDelay;\n let cap = renderNow + STREAM_FADE_DURATION;\n if (state === 'streaming') {\n revealedNewChars = true;\n const gapMs = Math.min(Math.max(renderNow - revealClock.lastTs, 16), MAX_REVEAL_GAP_MS);\n pace = Math.min(charDelay, Math.max(gapMs / newChars, MIN_STREAM_CHAR_PACE_MS));\n cap = renderNow + gapMs + STREAM_FADE_DURATION;\n }\n for (let i = births.length; i < blockCharCount; i++) {\n const prevBirth = i > 0 ? births[i - 1] : renderNow - pace;\n const chained = prevBirth + pace;\n births.push(Math.min(cap, Math.max(chained, renderNow)));\n }\n }\n\n let meta: BlockAnimationMeta;\n if (runtime.settled) {\n // Settled is monotone: a revealed block's births are frozen, so once\n // its last fade completed it stays settled until the runtime is\n // pruned by a stream restart.\n meta = { charDelay: runtime.charDelay ?? charDelay, settled: true };\n } else {\n const lastBirthTs = births.length > 0 ? (births.at(-1) ?? renderNow) : renderNow;\n meta = resolveBlockAnimationMeta({\n currentCharDelay: charDelay,\n fadeDuration: STREAM_FADE_DURATION,\n lastElapsedMs: renderNow - lastBirthTs,\n previousCharDelay: runtime.charDelay,\n state,\n });\n runtime.settled = meta.settled;\n }\n runtime.charDelay = meta.charDelay;\n\n blockAnimationMeta.set(block.startOffset, meta);\n }\n\n if (revealedNewChars) {\n revealClock.lastTs = renderNow;\n }\n\n for (const key of runtimes.keys()) {\n if (!alive.has(key)) {\n runtimes.delete(key);\n pluginsCache.delete(key);\n }\n }\n\n return blockAnimationMeta;\n};\n\ninterface StreamdownBlocksProps {\n content: string;\n markdownOptions: Omit<Options, 'children'>;\n}\n\nconst StreamdownBlocks = memo<StreamdownBlocksProps>(\n ({ content: smoothedContent, markdownOptions: rest }) => {\n const { streamAnimationGranularity = 'char' } = useMarkdownContext();\n const profiler = useStreamdownProfiler();\n const components = useMarkdownComponents();\n const baseRehypePlugins = useStablePlugins(useMarkdownRehypePlugins());\n const remarkPlugins = useStablePlugins(useMarkdownRemarkPlugins());\n const generatedId = useId();\n\n const processedContentResult = useMemo(() => {\n const start = profiler ? getNow() : 0;\n const value = remend(smoothedContent);\n\n return {\n durationMs: profiler ? getNow() - start : 0,\n value,\n };\n }, [profiler, smoothedContent]);\n const processedContent = processedContentResult.value;\n\n const blocksResult = useMemo(() => {\n const start = profiler ? getNow() : 0;\n const tokens = marked.lexer(processedContent);\n let offset = 0;\n\n const value = tokens.map((token) => {\n const block = { content: token.raw, startOffset: offset };\n offset += token.raw.length;\n return block;\n });\n\n return {\n durationMs: profiler ? getNow() - start : 0,\n value,\n };\n }, [processedContent, profiler]);\n const blocks: BlockInfo[] = blocksResult.value;\n\n const { getBlockState, charDelay } = useStreamQueue(blocks);\n const blockRuntimesRef = useRef<Map<number, BlockRuntime>>(new Map());\n const blockPluginsRef = useRef<Map<number, BlockPluginsCacheEntry>>(new Map());\n const revealClockRef = useRef<{ lastTs: number }>({ lastTs: 0 });\n\n const renderNow = getNow();\n\n const animationStart = profiler ? getNow() : 0;\n const blockAnimationMeta = updateBlockAnimation({\n blocks,\n charDelay,\n getBlockState,\n pluginsCache: blockPluginsRef.current,\n renderNow,\n revealClock: revealClockRef.current,\n runtimes: blockRuntimesRef.current,\n });\n const blockAnimationDurationMs = profiler ? getNow() - animationStart : 0;\n\n useEffect(() => {\n if (!profiler) return;\n\n profiler.recordCalculation({\n durationMs: processedContentResult.durationMs,\n name: 'content-normalize',\n textLength: processedContent.length,\n });\n }, [processedContent.length, processedContentResult.durationMs, profiler]);\n\n useEffect(() => {\n if (!profiler) return;\n\n profiler.recordCalculation({\n durationMs: blocksResult.durationMs,\n itemCount: blocks.length,\n name: 'block-lex',\n textLength: processedContent.length,\n });\n }, [blocks.length, blocksResult.durationMs, processedContent.length, profiler]);\n\n useEffect(() => {\n if (!profiler) return;\n\n profiler.recordCalculation({\n durationMs: blockAnimationDurationMs,\n itemCount: blocks.length,\n name: 'block-births',\n textLength: processedContent.length,\n });\n }, [blockAnimationDurationMs, blocks.length, processedContent.length, profiler]);\n\n const resolveBlockPlugins = (startOffset: number, settled: boolean): PluggableList => {\n if (settled) return baseRehypePlugins;\n\n const cache = blockPluginsRef.current;\n const entry = cache.get(startOffset);\n if (\n entry &&\n entry.base === baseRehypePlugins &&\n entry.granularity === streamAnimationGranularity\n ) {\n return entry.value;\n }\n\n const runtime = blockRuntimesRef.current.get(startOffset);\n const value: PluggableList = [\n ...baseRehypePlugins,\n [\n rehypeStreamAnimated,\n {\n fadeDuration: STREAM_FADE_DURATION,\n granularity: streamAnimationGranularity,\n runtime,\n },\n ],\n ];\n cache.set(startOffset, {\n base: baseRehypePlugins,\n granularity: streamAnimationGranularity,\n value,\n });\n return value;\n };\n\n const handleRootRender = useCallback<ProfilerOnRenderCallback>(\n (_, phase, actualDuration, baseDuration) => {\n profiler?.recordRootCommit({\n actualDuration,\n baseDuration,\n blockCount: blocks.length,\n phase,\n textLength: processedContent.length,\n });\n },\n [blocks.length, processedContent.length, profiler],\n );\n\n const handleBlockRender = useCallback<ProfilerOnRenderCallback>(\n (id, phase, actualDuration, baseDuration) => {\n if (!profiler) return;\n\n const [, indexText, offsetText] = id.split(':');\n const blockIndex = Number(indexText);\n\n if (!Number.isFinite(blockIndex)) return;\n\n const block = blocks[blockIndex];\n if (!block) return;\n\n profiler.recordBlockCommit({\n actualDuration,\n baseDuration,\n blockChars: countChars(block.content),\n blockIndex,\n blockKey: offsetText ?? String(block.startOffset),\n phase,\n state: getBlockState(blockIndex),\n });\n },\n [blocks, getBlockState, profiler],\n );\n\n const content = (\n <div className={styles.animated}>\n {blocks.map((block, index) => {\n const animationMeta = blockAnimationMeta.get(block.startOffset);\n if (!animationMeta) return null;\n\n const plugins = resolveBlockPlugins(block.startOffset, animationMeta.settled);\n const key = `${generatedId}-${block.startOffset}`;\n\n if (!profiler) {\n return (\n <StreamdownBlock\n {...rest}\n components={components}\n key={key}\n rehypePlugins={plugins}\n remarkPlugins={remarkPlugins}\n >\n {block.content}\n </StreamdownBlock>\n );\n }\n\n return (\n <Profiler\n id={`streamdown-block:${index}:${block.startOffset}`}\n key={key}\n onRender={handleBlockRender}\n >\n <StreamdownBlock\n {...rest}\n components={components}\n rehypePlugins={plugins}\n remarkPlugins={remarkPlugins}\n >\n {block.content}\n </StreamdownBlock>\n </Profiler>\n );\n })}\n </div>\n );\n\n if (!profiler) return content;\n\n return (\n <Profiler id={'streamdown-root'} onRender={handleRootRender}>\n {content}\n </Profiler>\n );\n },\n);\n\nStreamdownBlocks.displayName = 'StreamdownBlocks';\n\n// The outer component absorbs the upstream per-chunk prop churn: every\n// streamed chunk re-renders it, but it only feeds the smoother and renders\n// a memoized child keyed on the smoother's output — so the expensive block\n// pipeline runs per reveal commit, not per chunk AND per commit.\nexport const StreamdownRender = memo<Options>(({ children, ...rest }) => {\n const { streamSmoothingPreset = 'balanced' } = useMarkdownContext();\n const escapedContent = useMarkdownContent(children || '');\n const smoothedContent = useSmoothStreamContent(\n typeof escapedContent === 'string' ? escapedContent : '',\n { preset: streamSmoothingPreset },\n );\n const markdownOptions = useStableValue(rest);\n\n return <StreamdownBlocks content={smoothedContent} markdownOptions={markdownOptions} />;\n});\n\nStreamdownRender.displayName = 'StreamdownRender';\n\nexport default StreamdownRender;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/Markdown/SyntaxMarkdown/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nimport { fadeIn } from '@/styles/animations';\n\nexport const STREAM_FADE_DURATION = 180;\n\nexport const styles = createStaticStyles(({ css }) => {\n return {\n animated: css`\n .stream-char {\n opacity: 0;\n\n animation-name: ${fadeIn};\n animation-duration: ${STREAM_FADE_DURATION}ms;\n animation-timing-function: cubic-bezier(0.33, 0, 0.67, 1);\n animation-fill-mode: forwards;\n }\n\n .stream-char-revealed {\n opacity: 1;\n animation: none;\n }\n\n .katex-display .katex-html span {\n mask: none !important;\n animation: none !important;\n }\n `,\n };\n});\n"],"mappings":";;AAMA,MAAa,SAAS,oBAAoB,EAAE,UAAU;CACpD,OAAO,EACL,UAAU,GAAG;;;;0BAIS,OAAO;
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/Markdown/SyntaxMarkdown/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nimport { fadeIn } from '@/styles/animations';\n\nexport const STREAM_FADE_DURATION = 180;\n\nexport const styles = createStaticStyles(({ css }) => {\n return {\n animated: css`\n .stream-char {\n opacity: 0;\n\n animation-name: ${fadeIn};\n animation-duration: ${STREAM_FADE_DURATION}ms;\n animation-timing-function: cubic-bezier(0.33, 0, 0.67, 1);\n animation-fill-mode: forwards;\n }\n\n .stream-char-revealed {\n opacity: 1;\n animation: none;\n }\n\n .katex-display .katex-html span {\n mask: none !important;\n animation: none !important;\n }\n `,\n };\n});\n"],"mappings":";;AAMA,MAAa,SAAS,oBAAoB,EAAE,UAAU;CACpD,OAAO,EACL,UAAU,GAAG;;;;0BAIS,OAAO;8BACkB,IAAA;;;;;;;;;;;;;;MAejD;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.mjs","names":[],"sources":["../../../src/Markdown/components/CodeBlock.tsx"],"sourcesContent":["import { memo } from 'react';\n\nimport type { HighlighterProps } from '@/Highlighter';\nimport { FALLBACK_LANG } from '@/Highlighter/const';\nimport { isFullHtmlDocument } from '@/HtmlPreview/const';\nimport type { HtmlPreviewProps } from '@/HtmlPreview/type';\nimport Pre, { PreHtmlPreview, PreMermaid, PreSingleLine } from '@/mdx/mdxComponents/Pre';\nimport type { MermaidProps } from '@/Mermaid';\n\nconst countLines = (str: string): number => {\n const regex = /\\n/g;\n const matches = str.match(regex);\n return matches ? matches.length : 1;\n};\n\nexport const useCode = (raw: any) => {\n if (!raw) return;\n\n const { children = '', className } = raw?.props || { children: '' };\n\n if (!children) return;\n\n const content = Array.isArray(children) ? (children[0] as string) : children;\n\n const lang = className?.replace('language-', '') || FALLBACK_LANG;\n\n const isSingleLine = countLines(content) <= 1 && content.length <= 32;\n\n return {\n content,\n isSingleLine,\n lang,\n };\n};\n\ninterface CodeBlockProps {\n animated?: boolean;\n children: any;\n enableHtmlPreview?: boolean;\n enableMermaid?: boolean;\n fullFeatured?: boolean;\n highlight?: HighlighterProps;\n html?: HtmlPreviewProps;\n mermaid?: MermaidProps;\n}\n\nexport const CodeBlock = memo<CodeBlockProps>(\n ({\n fullFeatured,\n enableHtmlPreview,\n enableMermaid,\n highlight,\n html,\n mermaid,\n children,\n animated,\n ...rest\n }) => {\n const code = useCode(children);\n\n if (!code) return;\n\n if (enableMermaid && code.lang === 'mermaid')\n return (\n <PreMermaid animated={animated} fullFeatured={fullFeatured} {...mermaid} {...rest}>\n {code.content}\n </PreMermaid>\n );\n\n // Auto-route to HTML preview only for full HTML documents. Fragments fall\n // through to the normal highlighter — inline-rendering a `<div>` snippet\n // produces a degraded experience and risks hiding the actual code from\n // the reader.\n if (enableHtmlPreview && code.lang === 'html' && isFullHtmlDocument(code.content))\n return (\n <PreHtmlPreview animated={animated} fullFeatured={fullFeatured} {...html} {...rest}>\n {code.content}\n </PreHtmlPreview>\n );\n\n if (!highlight && code.isSingleLine)\n return <PreSingleLine language={code.lang}>{code.content}</PreSingleLine>;\n\n return (\n <Pre\n animated={animated}\n fullFeatured={fullFeatured}\n language={code.lang}\n {...highlight}\n {...rest}\n >\n {code.content}\n </Pre>\n );\n },\n (prevProps, nextProps) => prevProps.children === nextProps.children,\n);\n"],"mappings":";;;;;;AASA,MAAM,cAAc,QAAwB;CAE1C,MAAM,UAAU,IAAI,MAAM,KAAK;CAC/B,OAAO,UAAU,QAAQ,SAAS;AACpC;AAEA,MAAa,WAAW,QAAa;CACnC,IAAI,CAAC,KAAK;CAEV,MAAM,EAAE,WAAW,IAAI,cAAc,KAAK,SAAS,EAAE,UAAU,GAAG;CAElE,IAAI,CAAC,UAAU;CAEf,MAAM,UAAU,MAAM,QAAQ,QAAQ,IAAK,SAAS,KAAgB;CAEpE,MAAM,OAAO,WAAW,QAAQ,aAAa,EAAE,KAAA;CAI/C,OAAO;EACL;EACA,cAJmB,WAAW,OAAO,KAAK,KAAK,QAAQ,UAAU;EAKjE;CACF;AACF;AAaA,MAAa,YAAY,MACtB,EACC,cACA,mBACA,eACA,WACA,MACA,SACA,UACA,UACA,GAAG,WACC;CACJ,MAAM,OAAO,QAAQ,QAAQ;CAE7B,IAAI,CAAC,MAAM;CAEX,IAAI,iBAAiB,KAAK,SAAS,WACjC,OACE,oBAAC,YAAD;EAAsB;EAAwB;EAAc,GAAI;EAAS,GAAI;
|
|
1
|
+
{"version":3,"file":"CodeBlock.mjs","names":[],"sources":["../../../src/Markdown/components/CodeBlock.tsx"],"sourcesContent":["import { memo } from 'react';\n\nimport type { HighlighterProps } from '@/Highlighter';\nimport { FALLBACK_LANG } from '@/Highlighter/const';\nimport { isFullHtmlDocument } from '@/HtmlPreview/const';\nimport type { HtmlPreviewProps } from '@/HtmlPreview/type';\nimport Pre, { PreHtmlPreview, PreMermaid, PreSingleLine } from '@/mdx/mdxComponents/Pre';\nimport type { MermaidProps } from '@/Mermaid';\n\nconst countLines = (str: string): number => {\n const regex = /\\n/g;\n const matches = str.match(regex);\n return matches ? matches.length : 1;\n};\n\nexport const useCode = (raw: any) => {\n if (!raw) return;\n\n const { children = '', className } = raw?.props || { children: '' };\n\n if (!children) return;\n\n const content = Array.isArray(children) ? (children[0] as string) : children;\n\n const lang = className?.replace('language-', '') || FALLBACK_LANG;\n\n const isSingleLine = countLines(content) <= 1 && content.length <= 32;\n\n return {\n content,\n isSingleLine,\n lang,\n };\n};\n\ninterface CodeBlockProps {\n animated?: boolean;\n children: any;\n enableHtmlPreview?: boolean;\n enableMermaid?: boolean;\n fullFeatured?: boolean;\n highlight?: HighlighterProps;\n html?: HtmlPreviewProps;\n mermaid?: MermaidProps;\n}\n\nexport const CodeBlock = memo<CodeBlockProps>(\n ({\n fullFeatured,\n enableHtmlPreview,\n enableMermaid,\n highlight,\n html,\n mermaid,\n children,\n animated,\n ...rest\n }) => {\n const code = useCode(children);\n\n if (!code) return;\n\n if (enableMermaid && code.lang === 'mermaid')\n return (\n <PreMermaid animated={animated} fullFeatured={fullFeatured} {...mermaid} {...rest}>\n {code.content}\n </PreMermaid>\n );\n\n // Auto-route to HTML preview only for full HTML documents. Fragments fall\n // through to the normal highlighter — inline-rendering a `<div>` snippet\n // produces a degraded experience and risks hiding the actual code from\n // the reader.\n if (enableHtmlPreview && code.lang === 'html' && isFullHtmlDocument(code.content))\n return (\n <PreHtmlPreview animated={animated} fullFeatured={fullFeatured} {...html} {...rest}>\n {code.content}\n </PreHtmlPreview>\n );\n\n if (!highlight && code.isSingleLine)\n return <PreSingleLine language={code.lang}>{code.content}</PreSingleLine>;\n\n return (\n <Pre\n animated={animated}\n fullFeatured={fullFeatured}\n language={code.lang}\n {...highlight}\n {...rest}\n >\n {code.content}\n </Pre>\n );\n },\n (prevProps, nextProps) => prevProps.children === nextProps.children,\n);\n"],"mappings":";;;;;;AASA,MAAM,cAAc,QAAwB;CAE1C,MAAM,UAAU,IAAI,MAAM,KAAK;CAC/B,OAAO,UAAU,QAAQ,SAAS;AACpC;AAEA,MAAa,WAAW,QAAa;CACnC,IAAI,CAAC,KAAK;CAEV,MAAM,EAAE,WAAW,IAAI,cAAc,KAAK,SAAS,EAAE,UAAU,GAAG;CAElE,IAAI,CAAC,UAAU;CAEf,MAAM,UAAU,MAAM,QAAQ,QAAQ,IAAK,SAAS,KAAgB;CAEpE,MAAM,OAAO,WAAW,QAAQ,aAAa,EAAE,KAAA;CAI/C,OAAO;EACL;EACA,cAJmB,WAAW,OAAO,KAAK,KAAK,QAAQ,UAAU;EAKjE;CACF;AACF;AAaA,MAAa,YAAY,MACtB,EACC,cACA,mBACA,eACA,WACA,MACA,SACA,UACA,UACA,GAAG,WACC;CACJ,MAAM,OAAO,QAAQ,QAAQ;CAE7B,IAAI,CAAC,MAAM;CAEX,IAAI,iBAAiB,KAAK,SAAS,WACjC,OACE,oBAAC,YAAD;EAAsB;EAAwB;EAAc,GAAI;EAAS,GAAI;EAC1E,UAAA,KAAK;CACI,CAAA;CAOhB,IAAI,qBAAqB,KAAK,SAAS,UAAU,mBAAmB,KAAK,OAAO,GAC9E,OACE,oBAAC,gBAAD;EAA0B;EAAwB;EAAc,GAAI;EAAM,GAAI;EAC3E,UAAA,KAAK;CACQ,CAAA;CAGpB,IAAI,CAAC,aAAa,KAAK,cACrB,OAAO,oBAAC,eAAD;EAAe,UAAU,KAAK;EAAO,UAAA,KAAK;CAAuB,CAAA;CAE1E,OACE,oBAAC,KAAD;EACY;EACI;EACd,UAAU,KAAK;EACf,GAAI;EACJ,GAAI;EAEH,UAAA,KAAK;CACH,CAAA;AAET,IACC,WAAW,cAAc,UAAU,aAAa,UAAU,QAC7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Footnotes.mjs","names":["Flexbox"],"sources":["../../../src/Markdown/components/Footnotes.tsx"],"sourcesContent":["'use client';\n\nimport { memo, type ReactNode, useMemo } from 'react';\n\nimport A from '@/A';\nimport Block from '@/Block';\nimport { Flexbox } from '@/Flex';\nimport Text from '@/Text';\n\nimport SearchResultCards from './SearchResultCards';\n\ninterface FootnotesProps {\n 'children': ReactNode;\n 'data-footnote-links'?: string;\n 'data-footnotes'?: boolean;\n}\n\nconst DefaultFootnotes = memo<{ dataSource: any[] }>(({ dataSource }) => {\n const items = useMemo(\n () =>\n dataSource\n .find((child) => child?.type === 'ol')\n ?.props?.children?.map((item: any) => {\n if (typeof item === 'string' || item?.type !== 'li') return false;\n const data = item?.props?.children?.find((note: any) => note?.props?.children)?.props\n ?.children;\n if (!data || !Array.isArray(data)) return false;\n return {\n children: data[0],\n props: data[1]?.props || {},\n };\n })\n .filter(Boolean),\n [dataSource],\n );\n\n if (!Array.isArray(items)) return null;\n\n return (\n <Flexbox\n horizontal\n align={'flex-start'}\n as={'section'}\n className={'footnotes'}\n data-footnotes=\"true\"\n gap={'0.5em'}\n justify={'flex-start'}\n wrap={'wrap'}\n >\n {items.map(({ children, props }, index) => {\n const { node, href, ...rest } = props;\n const Container = href ? A : 'div';\n return (\n <Container {...(href ? { href, ...rest } : rest)} key={index}>\n <Block\n horizontal\n align={'stretch'}\n style={{ overflow: 'hidden', position: 'relative' }}\n variant={'outlined'}\n >\n <Block paddingInline={'0.66em'} style={{ borderRadius: 0 }} variant={'filled'}>\n <Text code as=\"span\" type={'secondary'}>\n {index + 1}\n </Text>\n </Block>\n <Text as=\"span\" style={{ paddingInline: '0.66em' }} type={'secondary'}>\n {children}\n </Text>\n </Block>\n </Container>\n );\n })}\n </Flexbox>\n );\n});\n\nconst Footnotes = memo<FootnotesProps>(({ children, ...rest }) => {\n const links = useMemo(() => {\n try {\n return JSON.parse(rest['data-footnote-links'] || '[]');\n } catch (error) {\n console.error('Failed to parse footnote links:', error);\n return [];\n }\n }, [rest['data-footnote-links']]);\n\n const isError = links.length === 0;\n\n if (!children) return;\n\n if (isError) {\n if (!Array.isArray(children)) return children;\n return <DefaultFootnotes dataSource={children} />;\n }\n\n return (\n <section className={'footnotes'} data-footnotes=\"true\">\n <SearchResultCards dataSource={links} />\n </section>\n );\n});\n\nFootnotes.displayName = 'Footnotes';\n\nexport default Footnotes;\n"],"mappings":";;;;;;;;;AAiBA,MAAM,mBAAmB,MAA6B,EAAE,iBAAiB;CACvE,MAAM,QAAQ,cAEV,WACG,MAAM,UAAU,OAAO,SAAS,IAAI,CAAC,EACpC,OAAO,UAAU,KAAK,SAAc;EACpC,IAAI,OAAO,SAAS,YAAY,MAAM,SAAS,MAAM,OAAO;EAC5D,MAAM,OAAO,MAAM,OAAO,UAAU,MAAM,SAAc,MAAM,OAAO,QAAQ,CAAC,EAAE,OAC5E;EACJ,IAAI,CAAC,QAAQ,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO;EAC1C,OAAO;GACL,UAAU,KAAK;GACf,OAAO,KAAK,EAAE,EAAE,SAAS,CAAC;EAC5B;CACF,CAAC,CAAC,CACD,OAAO,OAAO,GACnB,CAAC,UAAU,CACb;CAEA,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;CAElC,OACE,oBAACA,mBAAD;EACE,YAAA;EACA,OAAO;EACP,IAAI;EACJ,WAAW;EACX,kBAAe;EACf,KAAK;EACL,SAAS;EACT,MAAM;
|
|
1
|
+
{"version":3,"file":"Footnotes.mjs","names":["Flexbox"],"sources":["../../../src/Markdown/components/Footnotes.tsx"],"sourcesContent":["'use client';\n\nimport { memo, type ReactNode, useMemo } from 'react';\n\nimport A from '@/A';\nimport Block from '@/Block';\nimport { Flexbox } from '@/Flex';\nimport Text from '@/Text';\n\nimport SearchResultCards from './SearchResultCards';\n\ninterface FootnotesProps {\n 'children': ReactNode;\n 'data-footnote-links'?: string;\n 'data-footnotes'?: boolean;\n}\n\nconst DefaultFootnotes = memo<{ dataSource: any[] }>(({ dataSource }) => {\n const items = useMemo(\n () =>\n dataSource\n .find((child) => child?.type === 'ol')\n ?.props?.children?.map((item: any) => {\n if (typeof item === 'string' || item?.type !== 'li') return false;\n const data = item?.props?.children?.find((note: any) => note?.props?.children)?.props\n ?.children;\n if (!data || !Array.isArray(data)) return false;\n return {\n children: data[0],\n props: data[1]?.props || {},\n };\n })\n .filter(Boolean),\n [dataSource],\n );\n\n if (!Array.isArray(items)) return null;\n\n return (\n <Flexbox\n horizontal\n align={'flex-start'}\n as={'section'}\n className={'footnotes'}\n data-footnotes=\"true\"\n gap={'0.5em'}\n justify={'flex-start'}\n wrap={'wrap'}\n >\n {items.map(({ children, props }, index) => {\n const { node, href, ...rest } = props;\n const Container = href ? A : 'div';\n return (\n <Container {...(href ? { href, ...rest } : rest)} key={index}>\n <Block\n horizontal\n align={'stretch'}\n style={{ overflow: 'hidden', position: 'relative' }}\n variant={'outlined'}\n >\n <Block paddingInline={'0.66em'} style={{ borderRadius: 0 }} variant={'filled'}>\n <Text code as=\"span\" type={'secondary'}>\n {index + 1}\n </Text>\n </Block>\n <Text as=\"span\" style={{ paddingInline: '0.66em' }} type={'secondary'}>\n {children}\n </Text>\n </Block>\n </Container>\n );\n })}\n </Flexbox>\n );\n});\n\nconst Footnotes = memo<FootnotesProps>(({ children, ...rest }) => {\n const links = useMemo(() => {\n try {\n return JSON.parse(rest['data-footnote-links'] || '[]');\n } catch (error) {\n console.error('Failed to parse footnote links:', error);\n return [];\n }\n }, [rest['data-footnote-links']]);\n\n const isError = links.length === 0;\n\n if (!children) return;\n\n if (isError) {\n if (!Array.isArray(children)) return children;\n return <DefaultFootnotes dataSource={children} />;\n }\n\n return (\n <section className={'footnotes'} data-footnotes=\"true\">\n <SearchResultCards dataSource={links} />\n </section>\n );\n});\n\nFootnotes.displayName = 'Footnotes';\n\nexport default Footnotes;\n"],"mappings":";;;;;;;;;AAiBA,MAAM,mBAAmB,MAA6B,EAAE,iBAAiB;CACvE,MAAM,QAAQ,cAEV,WACG,MAAM,UAAU,OAAO,SAAS,IAAI,CAAC,EACpC,OAAO,UAAU,KAAK,SAAc;EACpC,IAAI,OAAO,SAAS,YAAY,MAAM,SAAS,MAAM,OAAO;EAC5D,MAAM,OAAO,MAAM,OAAO,UAAU,MAAM,SAAc,MAAM,OAAO,QAAQ,CAAC,EAAE,OAC5E;EACJ,IAAI,CAAC,QAAQ,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO;EAC1C,OAAO;GACL,UAAU,KAAK;GACf,OAAO,KAAK,EAAE,EAAE,SAAS,CAAC;EAC5B;CACF,CAAC,CAAC,CACD,OAAO,OAAO,GACnB,CAAC,UAAU,CACb;CAEA,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;CAElC,OACE,oBAACA,mBAAD;EACE,YAAA;EACA,OAAO;EACP,IAAI;EACJ,WAAW;EACX,kBAAe;EACf,KAAK;EACL,SAAS;EACT,MAAM;EAEL,UAAA,MAAM,KAAK,EAAE,UAAU,SAAS,UAAU;GACzC,MAAM,EAAE,MAAM,MAAM,GAAG,SAAS;GAEhC,OACE,8BAFgB,OAAO,IAAI,OAE3B;IAAW,GAAK,OAAO;KAAE;KAAM,GAAG;IAAK,IAAI;IAAO,KAAK;GAgB5C,GAfT,qBAAC,OAAD;IACE,YAAA;IACA,OAAO;IACP,OAAO;KAAE,UAAU;KAAU,UAAU;IAAW;IAClD,SAAS;IAJX,UAAA,CAME,oBAAC,OAAD;KAAO,eAAe;KAAU,OAAO,EAAE,cAAc,EAAE;KAAG,SAAS;KACnE,UAAA,oBAAC,MAAD;MAAM,MAAA;MAAK,IAAG;MAAO,MAAM;MACxB,UAAA,QAAQ;KACL,CAAA;IACD,CAAA,GACP,oBAAC,MAAD;KAAM,IAAG;KAAO,OAAO,EAAE,eAAe,SAAS;KAAG,MAAM;KACvD;IACG,CAAA,CACD;GACE,CAAA,CAAA;EAEf,CAAC;CACM,CAAA;AAEb,CAAC;AAED,MAAM,YAAY,MAAsB,EAAE,UAAU,GAAG,WAAW;CAChE,MAAM,QAAQ,cAAc;EAC1B,IAAI;GACF,OAAO,KAAK,MAAM,KAAK,0BAA0B,IAAI;EACvD,SAAS,OAAO;GACd,QAAQ,MAAM,mCAAmC,KAAK;GACtD,OAAO,CAAC;EACV;CACF,GAAG,CAAC,KAAK,sBAAsB,CAAC;CAEhC,MAAM,UAAU,MAAM,WAAW;CAEjC,IAAI,CAAC,UAAU;CAEf,IAAI,SAAS;EACX,IAAI,CAAC,MAAM,QAAQ,QAAQ,GAAG,OAAO;EACrC,OAAO,oBAAC,kBAAD,EAAkB,YAAY,SAAW,CAAA;CAClD;CAEA,OACE,oBAAC,WAAD;EAAS,WAAW;EAAa,kBAAe;EAC9C,UAAA,oBAAC,mBAAD,EAAmB,YAAY,MAAQ,CAAA;CAChC,CAAA;AAEb,CAAC;AAED,UAAU,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/Markdown/components/MarkdownTable/index.tsx"],"sourcesContent":["'use client';\n\nimport { createStyles } from 'antd-style';\nimport { memo, useCallback, useRef } from 'react';\n\nimport CopyButton from '@/CopyButton';\n\nimport { hastTableToMarkdown } from './hastTableToMarkdown';\n\nconst useStyles = createStyles(({ css, token }) => ({\n copyButton: css`\n position: absolute;\n z-index: 1;\n\n /* Vertical center of the header row = top padding (0.75em) + half of\n the text line-box (line-height * 0.5em). Pulling the button up by\n 50% of its own height with transform parks it on that exact line. */\n inset-block-start: calc(0.75em + (var(--lobe-markdown-line-height) * 0.5em));\n inset-inline-end: 0.5em;\n transform: translateY(-50%);\n\n opacity: 0;\n background: ${token.colorBgContainer};\n box-shadow: 0 0 0 1px ${token.colorBorderSecondary};\n\n transition: opacity ${token.motionDurationMid} ${token.motionEaseInOut};\n `,\n wrapper: css`\n position: relative;\n\n display: block;\n\n width: max-content;\n max-width: 100%;\n margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n\n &:hover .table-copy-button,\n &:focus-within .table-copy-button {\n opacity: 1;\n }\n\n /* Hand spacing to the wrapper so the absolutely-positioned copy\n button anchors against the visible table edge instead of empty\n margin space. */\n > table {\n margin-block: 0;\n }\n\n /* Reserve room for the copy button so right-aligned header text\n doesn't slide under it. */\n > table thead th:last-child {\n padding-inline-end: calc(1em + 32px);\n }\n `,\n}));\n\ninterface MarkdownTableProps {\n children?: React.ReactNode;\n node?: any;\n}\n\nconst MarkdownTable = memo<MarkdownTableProps>(({ node, children, ...rest }) => {\n const { styles, cx } = useStyles();\n const nodeRef = useRef(node);\n nodeRef.current = node;\n\n const getMarkdown = useCallback(() => hastTableToMarkdown(nodeRef.current), []);\n\n return (\n <div className={styles.wrapper}>\n <CopyButton\n className={cx(styles.copyButton, 'table-copy-button')}\n content={getMarkdown}\n glass={false}\n size={{ blockSize: 24, size: 14 }}\n title=\"Copy table\"\n variant=\"filled\"\n />\n <table {...rest}>{children}</table>\n </div>\n );\n});\n\nMarkdownTable.displayName = 'MarkdownTable';\n\nexport default MarkdownTable;\n"],"mappings":";;;;;;;AASA,MAAM,YAAY,cAAc,EAAE,KAAK,aAAa;CAClD,YAAY,GAAG;;;;;;;;;;;;kBAYC,MAAM,iBAAiB;4BACb,MAAM,qBAAqB;;0BAE7B,MAAM,kBAAkB,GAAG,MAAM,gBAAgB;;CAEzE,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2Bd,EAAE;AAOF,MAAM,gBAAgB,MAA0B,EAAE,MAAM,UAAU,GAAG,WAAW;CAC9E,MAAM,EAAE,QAAQ,OAAO,UAAU;CACjC,MAAM,UAAU,OAAO,IAAI;CAC3B,QAAQ,UAAU;CAElB,MAAM,cAAc,kBAAkB,oBAAoB,QAAQ,OAAO,GAAG,CAAC,CAAC;CAE9E,OACE,qBAAC,OAAD;EAAK,WAAW,OAAO;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/Markdown/components/MarkdownTable/index.tsx"],"sourcesContent":["'use client';\n\nimport { createStyles } from 'antd-style';\nimport { memo, useCallback, useRef } from 'react';\n\nimport CopyButton from '@/CopyButton';\n\nimport { hastTableToMarkdown } from './hastTableToMarkdown';\n\nconst useStyles = createStyles(({ css, token }) => ({\n copyButton: css`\n position: absolute;\n z-index: 1;\n\n /* Vertical center of the header row = top padding (0.75em) + half of\n the text line-box (line-height * 0.5em). Pulling the button up by\n 50% of its own height with transform parks it on that exact line. */\n inset-block-start: calc(0.75em + (var(--lobe-markdown-line-height) * 0.5em));\n inset-inline-end: 0.5em;\n transform: translateY(-50%);\n\n opacity: 0;\n background: ${token.colorBgContainer};\n box-shadow: 0 0 0 1px ${token.colorBorderSecondary};\n\n transition: opacity ${token.motionDurationMid} ${token.motionEaseInOut};\n `,\n wrapper: css`\n position: relative;\n\n display: block;\n\n width: max-content;\n max-width: 100%;\n margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);\n\n &:hover .table-copy-button,\n &:focus-within .table-copy-button {\n opacity: 1;\n }\n\n /* Hand spacing to the wrapper so the absolutely-positioned copy\n button anchors against the visible table edge instead of empty\n margin space. */\n > table {\n margin-block: 0;\n }\n\n /* Reserve room for the copy button so right-aligned header text\n doesn't slide under it. */\n > table thead th:last-child {\n padding-inline-end: calc(1em + 32px);\n }\n `,\n}));\n\ninterface MarkdownTableProps {\n children?: React.ReactNode;\n node?: any;\n}\n\nconst MarkdownTable = memo<MarkdownTableProps>(({ node, children, ...rest }) => {\n const { styles, cx } = useStyles();\n const nodeRef = useRef(node);\n nodeRef.current = node;\n\n const getMarkdown = useCallback(() => hastTableToMarkdown(nodeRef.current), []);\n\n return (\n <div className={styles.wrapper}>\n <CopyButton\n className={cx(styles.copyButton, 'table-copy-button')}\n content={getMarkdown}\n glass={false}\n size={{ blockSize: 24, size: 14 }}\n title=\"Copy table\"\n variant=\"filled\"\n />\n <table {...rest}>{children}</table>\n </div>\n );\n});\n\nMarkdownTable.displayName = 'MarkdownTable';\n\nexport default MarkdownTable;\n"],"mappings":";;;;;;;AASA,MAAM,YAAY,cAAc,EAAE,KAAK,aAAa;CAClD,YAAY,GAAG;;;;;;;;;;;;kBAYC,MAAM,iBAAiB;4BACb,MAAM,qBAAqB;;0BAE7B,MAAM,kBAAkB,GAAG,MAAM,gBAAgB;;CAEzE,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2Bd,EAAE;AAOF,MAAM,gBAAgB,MAA0B,EAAE,MAAM,UAAU,GAAG,WAAW;CAC9E,MAAM,EAAE,QAAQ,OAAO,UAAU;CACjC,MAAM,UAAU,OAAO,IAAI;CAC3B,QAAQ,UAAU;CAElB,MAAM,cAAc,kBAAkB,oBAAoB,QAAQ,OAAO,GAAG,CAAC,CAAC;CAE9E,OACE,qBAAC,OAAD;EAAK,WAAW,OAAO;EAAvB,UAAA,CACE,oBAAC,YAAD;GACE,WAAW,GAAG,OAAO,YAAY,mBAAmB;GACpD,SAAS;GACT,OAAO;GACP,MAAM;IAAE,WAAW;IAAI,MAAM;GAAG;GAChC,OAAM;GACN,SAAQ;EACT,CAAA,GACD,oBAAC,SAAD;GAAO,GAAI;GAAO;EAAgB,CAAA,CAC/B;;AAET,CAAC;AAED,cAAc,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchResultCard.mjs","names":["Flexbox"],"sources":["../../../../src/Markdown/components/SearchResultCards/SearchResultCard.tsx"],"sourcesContent":["'use client';\n\nimport { memo, type Ref, useMemo } from 'react';\n\nimport A from '@/A';\nimport Block from '@/Block';\nimport { Flexbox } from '@/Flex';\nimport Img from '@/Img';\nimport Text from '@/Text';\nimport { type AProps } from '@/types';\n\nimport { styles } from './style';\n\nexport interface SearchResultCardProps extends AProps {\n alt?: string;\n ref?: Ref<HTMLAnchorElement>;\n title?: string;\n url: string;\n}\n\nconst SearchResultCard = memo<SearchResultCardProps>(({ ref, url, title, alt, ...rest }) => {\n const [displayTitle, domain, host] = useMemo(() => {\n try {\n const urlObj = new URL(url);\n const domain = urlObj.hostname.replace('www.', '');\n const hostForUrl = urlObj.host;\n\n let displayTitle = title;\n if (title === url) {\n displayTitle = hostForUrl + urlObj.pathname;\n }\n\n return [displayTitle, domain, hostForUrl];\n } catch {\n return [title, url, url];\n }\n }, [url, title]);\n\n return (\n <A href={url} ref={ref} rel=\"noreferrer\" target={'_blank'} {...rest}>\n <Block\n clickable\n className={styles.container}\n gap={2}\n justify={'space-between'}\n key={url}\n paddingBlock={6}\n paddingInline={8}\n variant={'outlined'}\n >\n <Text ellipsis={{ rows: 2 }}>{displayTitle}</Text>\n <Flexbox horizontal align={'center'} gap={4}>\n <Img\n alt={alt || title || url}\n height={14}\n src={`https://icons.duckduckgo.com/ip3/${host}.ico`}\n width={14}\n />\n <Text ellipsis className={styles.url} type={'secondary'}>\n {domain}\n </Text>\n </Flexbox>\n </Block>\n </A>\n );\n});\n\nSearchResultCard.displayName = 'SearchResultCard';\n\nexport default SearchResultCard;\n"],"mappings":";;;;;;;;;;AAoBA,MAAM,mBAAmB,MAA6B,EAAE,KAAK,KAAK,OAAO,KAAK,GAAG,WAAW;CAC1F,MAAM,CAAC,cAAc,QAAQ,QAAQ,cAAc;EACjD,IAAI;GACF,MAAM,SAAS,IAAI,IAAI,GAAG;GAC1B,MAAM,SAAS,OAAO,SAAS,QAAQ,QAAQ,EAAE;GACjD,MAAM,aAAa,OAAO;GAE1B,IAAI,eAAe;GACnB,IAAI,UAAU,KACZ,eAAe,aAAa,OAAO;GAGrC,OAAO;IAAC;IAAc;IAAQ;GAAU;EAC1C,QAAQ;GACN,OAAO;IAAC;IAAO;IAAK;GAAG;EACzB;CACF,GAAG,CAAC,KAAK,KAAK,CAAC;CAEf,OACE,oBAAC,GAAD;EAAG,MAAM;EAAU;EAAK,KAAI;EAAa,QAAQ;EAAU,GAAI;
|
|
1
|
+
{"version":3,"file":"SearchResultCard.mjs","names":["Flexbox"],"sources":["../../../../src/Markdown/components/SearchResultCards/SearchResultCard.tsx"],"sourcesContent":["'use client';\n\nimport { memo, type Ref, useMemo } from 'react';\n\nimport A from '@/A';\nimport Block from '@/Block';\nimport { Flexbox } from '@/Flex';\nimport Img from '@/Img';\nimport Text from '@/Text';\nimport { type AProps } from '@/types';\n\nimport { styles } from './style';\n\nexport interface SearchResultCardProps extends AProps {\n alt?: string;\n ref?: Ref<HTMLAnchorElement>;\n title?: string;\n url: string;\n}\n\nconst SearchResultCard = memo<SearchResultCardProps>(({ ref, url, title, alt, ...rest }) => {\n const [displayTitle, domain, host] = useMemo(() => {\n try {\n const urlObj = new URL(url);\n const domain = urlObj.hostname.replace('www.', '');\n const hostForUrl = urlObj.host;\n\n let displayTitle = title;\n if (title === url) {\n displayTitle = hostForUrl + urlObj.pathname;\n }\n\n return [displayTitle, domain, hostForUrl];\n } catch {\n return [title, url, url];\n }\n }, [url, title]);\n\n return (\n <A href={url} ref={ref} rel=\"noreferrer\" target={'_blank'} {...rest}>\n <Block\n clickable\n className={styles.container}\n gap={2}\n justify={'space-between'}\n key={url}\n paddingBlock={6}\n paddingInline={8}\n variant={'outlined'}\n >\n <Text ellipsis={{ rows: 2 }}>{displayTitle}</Text>\n <Flexbox horizontal align={'center'} gap={4}>\n <Img\n alt={alt || title || url}\n height={14}\n src={`https://icons.duckduckgo.com/ip3/${host}.ico`}\n width={14}\n />\n <Text ellipsis className={styles.url} type={'secondary'}>\n {domain}\n </Text>\n </Flexbox>\n </Block>\n </A>\n );\n});\n\nSearchResultCard.displayName = 'SearchResultCard';\n\nexport default SearchResultCard;\n"],"mappings":";;;;;;;;;;AAoBA,MAAM,mBAAmB,MAA6B,EAAE,KAAK,KAAK,OAAO,KAAK,GAAG,WAAW;CAC1F,MAAM,CAAC,cAAc,QAAQ,QAAQ,cAAc;EACjD,IAAI;GACF,MAAM,SAAS,IAAI,IAAI,GAAG;GAC1B,MAAM,SAAS,OAAO,SAAS,QAAQ,QAAQ,EAAE;GACjD,MAAM,aAAa,OAAO;GAE1B,IAAI,eAAe;GACnB,IAAI,UAAU,KACZ,eAAe,aAAa,OAAO;GAGrC,OAAO;IAAC;IAAc;IAAQ;GAAU;EAC1C,QAAQ;GACN,OAAO;IAAC;IAAO;IAAK;GAAG;EACzB;CACF,GAAG,CAAC,KAAK,KAAK,CAAC;CAEf,OACE,oBAAC,GAAD;EAAG,MAAM;EAAU;EAAK,KAAI;EAAa,QAAQ;EAAU,GAAI;EAC7D,UAAA,qBAAC,OAAD;GACE,WAAA;GACA,WAAW,OAAO;GAClB,KAAK;GACL,SAAS;GAET,cAAc;GACd,eAAe;GACf,SAAS;GARX,UAAA,CAUE,oBAAC,MAAD;IAAM,UAAU,EAAE,MAAM,EAAE;IAAI,UAAA;GAAmB,CAAA,GACjD,qBAACA,mBAAD;IAAS,YAAA;IAAW,OAAO;IAAU,KAAK;IAA1C,UAAA,CACE,oBAAC,KAAD;KACE,KAAK,OAAO,SAAS;KACrB,QAAQ;KACR,KAAK,oCAAoC,KAAK;KAC9C,OAAO;IACR,CAAA,GACD,oBAAC,MAAD;KAAM,UAAA;KAAS,WAAW,OAAO;KAAK,MAAM;KACzC,UAAA;IACG,CAAA,CACC;GACJ,CAAA,CAAA;EAjBA,GAAA,GAiBA;CACN,CAAA;AAEP,CAAC;AAED,iBAAiB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/Markdown/components/SearchResultCards/index.tsx"],"sourcesContent":["'use client';\n\nimport { memo, type Ref } from 'react';\n\nimport { type FlexboxProps } from '@/Flex';\nimport ScrollShadow from '@/ScrollShadow';\n\nimport SearchResultCard from './SearchResultCard';\n\nexport interface SearchResultItem {\n alt?: string;\n summary?: string;\n title?: string;\n url: string;\n}\n\nexport interface SearchResultCardsProps extends FlexboxProps {\n dataSource: string[] | SearchResultItem[];\n ref?: Ref<HTMLDivElement>;\n}\n\nconst SearchResultCards = memo<SearchResultCardsProps>(({ ref, dataSource, style, ...rest }) => {\n return (\n <ScrollShadow\n hideScrollBar\n horizontal\n gap={12}\n orientation={'horizontal'}\n ref={ref}\n size={10}\n style={{ minHeight: 80, overflowX: 'scroll', paddingInlineEnd: 24, width: '100%', ...style }}\n {...rest}\n >\n {dataSource.map((link) =>\n typeof link === 'string' ? (\n <SearchResultCard key={link} url={link} />\n ) : (\n <SearchResultCard key={link.url} {...link} />\n ),\n )}\n </ScrollShadow>\n );\n});\n\nSearchResultCards.displayName = 'SearchResultCards';\n\nexport default SearchResultCards;\n"],"mappings":";;;;;;AAqBA,MAAM,oBAAoB,MAA8B,EAAE,KAAK,YAAY,OAAO,GAAG,WAAW;CAC9F,OACE,oBAAC,cAAD;EACE,eAAA;EACA,YAAA;EACA,KAAK;EACL,aAAa;EACR;EACL,MAAM;EACN,OAAO;GAAE,WAAW;GAAI,WAAW;GAAU,kBAAkB;GAAI,OAAO;GAAQ,GAAG;EAAM;EAC3F,GAAI;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/Markdown/components/SearchResultCards/index.tsx"],"sourcesContent":["'use client';\n\nimport { memo, type Ref } from 'react';\n\nimport { type FlexboxProps } from '@/Flex';\nimport ScrollShadow from '@/ScrollShadow';\n\nimport SearchResultCard from './SearchResultCard';\n\nexport interface SearchResultItem {\n alt?: string;\n summary?: string;\n title?: string;\n url: string;\n}\n\nexport interface SearchResultCardsProps extends FlexboxProps {\n dataSource: string[] | SearchResultItem[];\n ref?: Ref<HTMLDivElement>;\n}\n\nconst SearchResultCards = memo<SearchResultCardsProps>(({ ref, dataSource, style, ...rest }) => {\n return (\n <ScrollShadow\n hideScrollBar\n horizontal\n gap={12}\n orientation={'horizontal'}\n ref={ref}\n size={10}\n style={{ minHeight: 80, overflowX: 'scroll', paddingInlineEnd: 24, width: '100%', ...style }}\n {...rest}\n >\n {dataSource.map((link) =>\n typeof link === 'string' ? (\n <SearchResultCard key={link} url={link} />\n ) : (\n <SearchResultCard key={link.url} {...link} />\n ),\n )}\n </ScrollShadow>\n );\n});\n\nSearchResultCards.displayName = 'SearchResultCards';\n\nexport default SearchResultCards;\n"],"mappings":";;;;;;AAqBA,MAAM,oBAAoB,MAA8B,EAAE,KAAK,YAAY,OAAO,GAAG,WAAW;CAC9F,OACE,oBAAC,cAAD;EACE,eAAA;EACA,YAAA;EACA,KAAK;EACL,aAAa;EACR;EACL,MAAM;EACN,OAAO;GAAE,WAAW;GAAI,WAAW;GAAU,kBAAkB;GAAI,OAAO;GAAQ,GAAG;EAAM;EAC3F,GAAI;EAEH,UAAA,WAAW,KAAK,SACf,OAAO,SAAS,WACd,oBAAC,kBAAD,EAA6B,KAAK,KAAO,GAAlB,IAAkB,IAEzC,oBAAC,kBAAD,EAAiC,GAAI,KAAO,GAArB,KAAK,GAAgB,CAEhD;CACY,CAAA;AAElB,CAAC;AAED,kBAAkB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaterialFileTypeIcon.mjs","names":[],"sources":["../../src/MaterialFileTypeIcon/MaterialFileTypeIcon.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, useMemo } from 'react';\n\nimport { useCdnFn } from '@/ConfigProvider';\nimport FileTypeIcon from '@/FileTypeIcon';\nimport { Center } from '@/Flex';\nimport Img from '@/Img';\n\nimport type { MaterialFileTypeIconProps } from './type';\nimport { getIconUrlForDirectoryPath, getIconUrlForFilePath } from './utils';\n\nconst MaterialFileTypeIcon: FC<MaterialFileTypeIconProps> = ({\n fallbackUnknownType = true,\n filename,\n size = 48,\n variant = 'raw',\n type,\n style,\n open,\n ...rest\n}) => {\n const genCdnUrl = useCdnFn();\n const ICONS_URL = genCdnUrl({\n path: 'assets',\n pkg: '@lobehub/assets-fileicon',\n version: '1.0.0',\n });\n\n const iconUrl: string = useMemo(() => {\n return type === 'file'\n ? getIconUrlForFilePath({ fallbackUnknownType, iconsUrl: ICONS_URL, path: filename })\n : getIconUrlForDirectoryPath({\n fallbackUnknownType,\n iconsUrl: ICONS_URL,\n open,\n path: filename,\n });\n }, [ICONS_URL, type, filename, open]);\n\n if (!iconUrl)\n return (\n <FileTypeIcon\n className={rest.className}\n filetype={filename.split('.')[1]}\n size={size}\n type={type}\n variant={'mono'}\n />\n );\n\n if (variant === 'raw')\n return <Img alt={filename} height={size} src={iconUrl} style={style} width={size} {...rest} />;\n\n return (\n <Center\n flex={'none'}\n height={size}\n style={{ position: 'relative', ...style }}\n width={size}\n {...rest}\n >\n <FileTypeIcon size={size} type={variant} variant={'mono'} />\n <Img\n alt={filename}\n height={size / 2}\n src={iconUrl}\n style={{ position: 'absolute', top: size / 3 }}\n width={size / 2}\n {...rest}\n />\n </Center>\n );\n};\n\nMaterialFileTypeIcon.displayName = 'MaterialFileTypeIcon';\n\nexport default MaterialFileTypeIcon;\n"],"mappings":";;;;;;;;;AAYA,MAAM,wBAAuD,EAC3D,sBAAsB,MACtB,UACA,OAAO,IACP,UAAU,OACV,MACA,OACA,MACA,GAAG,WACC;CAEJ,MAAM,YADY,SACQ,CAAC,CAAC;EAC1B,MAAM;EACN,KAAK;EACL,SAAS;CACX,CAAC;CAED,MAAM,UAAkB,cAAc;EACpC,OAAO,SAAS,SACZ,sBAAsB;GAAE;GAAqB,UAAU;GAAW,MAAM;EAAS,CAAC,IAClF,2BAA2B;GACzB;GACA,UAAU;GACV;GACA,MAAM;EACR,CAAC;CACP,GAAG;EAAC;EAAW;EAAM;EAAU;CAAI,CAAC;CAEpC,IAAI,CAAC,SACH,OACE,oBAAC,cAAD;EACE,WAAW,KAAK;EAChB,UAAU,SAAS,MAAM,GAAG,CAAC,CAAC;EACxB;EACA;EACN,SAAS;CACV,CAAA;CAGL,IAAI,YAAY,OACd,OAAO,oBAAC,KAAD;EAAK,KAAK;EAAU,QAAQ;EAAM,KAAK;EAAgB;EAAO,OAAO;EAAM,GAAI;CAAO,CAAA;CAE/F,OACE,qBAAC,QAAD;EACE,MAAM;EACN,QAAQ;EACR,OAAO;GAAE,UAAU;GAAY,GAAG;EAAM;EACxC,OAAO;EACP,GAAI;
|
|
1
|
+
{"version":3,"file":"MaterialFileTypeIcon.mjs","names":[],"sources":["../../src/MaterialFileTypeIcon/MaterialFileTypeIcon.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, useMemo } from 'react';\n\nimport { useCdnFn } from '@/ConfigProvider';\nimport FileTypeIcon from '@/FileTypeIcon';\nimport { Center } from '@/Flex';\nimport Img from '@/Img';\n\nimport type { MaterialFileTypeIconProps } from './type';\nimport { getIconUrlForDirectoryPath, getIconUrlForFilePath } from './utils';\n\nconst MaterialFileTypeIcon: FC<MaterialFileTypeIconProps> = ({\n fallbackUnknownType = true,\n filename,\n size = 48,\n variant = 'raw',\n type,\n style,\n open,\n ...rest\n}) => {\n const genCdnUrl = useCdnFn();\n const ICONS_URL = genCdnUrl({\n path: 'assets',\n pkg: '@lobehub/assets-fileicon',\n version: '1.0.0',\n });\n\n const iconUrl: string = useMemo(() => {\n return type === 'file'\n ? getIconUrlForFilePath({ fallbackUnknownType, iconsUrl: ICONS_URL, path: filename })\n : getIconUrlForDirectoryPath({\n fallbackUnknownType,\n iconsUrl: ICONS_URL,\n open,\n path: filename,\n });\n }, [ICONS_URL, type, filename, open]);\n\n if (!iconUrl)\n return (\n <FileTypeIcon\n className={rest.className}\n filetype={filename.split('.')[1]}\n size={size}\n type={type}\n variant={'mono'}\n />\n );\n\n if (variant === 'raw')\n return <Img alt={filename} height={size} src={iconUrl} style={style} width={size} {...rest} />;\n\n return (\n <Center\n flex={'none'}\n height={size}\n style={{ position: 'relative', ...style }}\n width={size}\n {...rest}\n >\n <FileTypeIcon size={size} type={variant} variant={'mono'} />\n <Img\n alt={filename}\n height={size / 2}\n src={iconUrl}\n style={{ position: 'absolute', top: size / 3 }}\n width={size / 2}\n {...rest}\n />\n </Center>\n );\n};\n\nMaterialFileTypeIcon.displayName = 'MaterialFileTypeIcon';\n\nexport default MaterialFileTypeIcon;\n"],"mappings":";;;;;;;;;AAYA,MAAM,wBAAuD,EAC3D,sBAAsB,MACtB,UACA,OAAO,IACP,UAAU,OACV,MACA,OACA,MACA,GAAG,WACC;CAEJ,MAAM,YADY,SACQ,CAAC,CAAC;EAC1B,MAAM;EACN,KAAK;EACL,SAAS;CACX,CAAC;CAED,MAAM,UAAkB,cAAc;EACpC,OAAO,SAAS,SACZ,sBAAsB;GAAE;GAAqB,UAAU;GAAW,MAAM;EAAS,CAAC,IAClF,2BAA2B;GACzB;GACA,UAAU;GACV;GACA,MAAM;EACR,CAAC;CACP,GAAG;EAAC;EAAW;EAAM;EAAU;CAAI,CAAC;CAEpC,IAAI,CAAC,SACH,OACE,oBAAC,cAAD;EACE,WAAW,KAAK;EAChB,UAAU,SAAS,MAAM,GAAG,CAAC,CAAC;EACxB;EACA;EACN,SAAS;CACV,CAAA;CAGL,IAAI,YAAY,OACd,OAAO,oBAAC,KAAD;EAAK,KAAK;EAAU,QAAQ;EAAM,KAAK;EAAgB;EAAO,OAAO;EAAM,GAAI;CAAO,CAAA;CAE/F,OACE,qBAAC,QAAD;EACE,MAAM;EACN,QAAQ;EACR,OAAO;GAAE,UAAU;GAAY,GAAG;EAAM;EACxC,OAAO;EACP,GAAI;EALN,UAAA,CAOE,oBAAC,cAAD;GAAoB;GAAM,MAAM;GAAS,SAAS;EAAS,CAAA,GAC3D,oBAAC,KAAD;GACE,KAAK;GACL,QAAQ,OAAO;GACf,KAAK;GACL,OAAO;IAAE,UAAU;IAAY,KAAK,OAAO;GAAE;GAC7C,OAAO,OAAO;GACd,GAAI;EACL,CAAA,CACK;;AAEZ;AAEA,qBAAqB,cAAc"}
|
package/es/Menu/Menu.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.mjs","names":["Menu","AntdMenu"],"sources":["../../src/Menu/Menu.tsx"],"sourcesContent":["'use client';\n\nimport { ConfigProvider, Menu as AntdMenu } from 'antd';\nimport { cx, useTheme } from 'antd-style';\nimport { memo, useMemo } from 'react';\n\nimport { IconProvider } from '@/Icon';\nimport { mapItems } from '@/Menu/utils';\n\nimport { variants } from './style';\nimport { type MenuProps } from './type';\n\nconst Menu = memo<MenuProps>(\n ({\n compact,\n shadow,\n variant = 'borderless',\n className,\n selectable,\n iconProps,\n items,\n ref,\n ...rest\n }) => {\n const theme = useTheme();\n\n const antdItems = useMemo(() => items.map((item) => mapItems(item)), [items]);\n\n return (\n <ConfigProvider\n theme={{\n components: {\n Menu: {\n controlHeightLG: 36,\n iconMarginInlineEnd: 8,\n iconSize: 16,\n itemActiveBg: theme.isDarkMode ? theme.colorFillQuaternary : theme.colorFillSecondary,\n itemBorderRadius: theme.borderRadius,\n itemColor: theme.colorTextSecondary,\n itemHoverBg: theme.colorFillTertiary,\n itemMarginBlock: 4,\n itemMarginInline: 4,\n itemSelectedBg: theme.colorFillSecondary,\n },\n },\n }}\n >\n <IconProvider\n config={{\n size: 'small',\n ...iconProps,\n }}\n >\n <AntdMenu\n className={cx(variants({ compact, shadow, variant }), className)}\n inlineIndent={12}\n items={antdItems}\n mode=\"vertical\"\n ref={ref}\n selectable={selectable}\n {...rest}\n />\n </IconProvider>\n </ConfigProvider>\n );\n },\n);\n\nMenu.displayName = 'Menu';\n\nexport default Menu;\n"],"mappings":";;;;;;;;;AAYA,MAAMA,SAAO,MACV,EACC,SACA,QACA,UAAU,cACV,WACA,YACA,WACA,OACA,KACA,GAAG,WACC;CACJ,MAAM,QAAQ,SAAS;CAEvB,MAAM,YAAY,cAAc,MAAM,KAAK,SAAS,SAAS,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;CAE5E,OACE,oBAAC,gBAAD;EACE,OAAO,EACL,YAAY,EACV,MAAM;GACJ,iBAAiB;GACjB,qBAAqB;GACrB,UAAU;GACV,cAAc,MAAM,aAAa,MAAM,sBAAsB,MAAM;GACnE,kBAAkB,MAAM;GACxB,WAAW,MAAM;GACjB,aAAa,MAAM;GACnB,iBAAiB;GACjB,kBAAkB;GAClB,gBAAgB,MAAM;EACxB,EACF,EACF;
|
|
1
|
+
{"version":3,"file":"Menu.mjs","names":["Menu","AntdMenu"],"sources":["../../src/Menu/Menu.tsx"],"sourcesContent":["'use client';\n\nimport { ConfigProvider, Menu as AntdMenu } from 'antd';\nimport { cx, useTheme } from 'antd-style';\nimport { memo, useMemo } from 'react';\n\nimport { IconProvider } from '@/Icon';\nimport { mapItems } from '@/Menu/utils';\n\nimport { variants } from './style';\nimport { type MenuProps } from './type';\n\nconst Menu = memo<MenuProps>(\n ({\n compact,\n shadow,\n variant = 'borderless',\n className,\n selectable,\n iconProps,\n items,\n ref,\n ...rest\n }) => {\n const theme = useTheme();\n\n const antdItems = useMemo(() => items.map((item) => mapItems(item)), [items]);\n\n return (\n <ConfigProvider\n theme={{\n components: {\n Menu: {\n controlHeightLG: 36,\n iconMarginInlineEnd: 8,\n iconSize: 16,\n itemActiveBg: theme.isDarkMode ? theme.colorFillQuaternary : theme.colorFillSecondary,\n itemBorderRadius: theme.borderRadius,\n itemColor: theme.colorTextSecondary,\n itemHoverBg: theme.colorFillTertiary,\n itemMarginBlock: 4,\n itemMarginInline: 4,\n itemSelectedBg: theme.colorFillSecondary,\n },\n },\n }}\n >\n <IconProvider\n config={{\n size: 'small',\n ...iconProps,\n }}\n >\n <AntdMenu\n className={cx(variants({ compact, shadow, variant }), className)}\n inlineIndent={12}\n items={antdItems}\n mode=\"vertical\"\n ref={ref}\n selectable={selectable}\n {...rest}\n />\n </IconProvider>\n </ConfigProvider>\n );\n },\n);\n\nMenu.displayName = 'Menu';\n\nexport default Menu;\n"],"mappings":";;;;;;;;;AAYA,MAAMA,SAAO,MACV,EACC,SACA,QACA,UAAU,cACV,WACA,YACA,WACA,OACA,KACA,GAAG,WACC;CACJ,MAAM,QAAQ,SAAS;CAEvB,MAAM,YAAY,cAAc,MAAM,KAAK,SAAS,SAAS,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;CAE5E,OACE,oBAAC,gBAAD;EACE,OAAO,EACL,YAAY,EACV,MAAM;GACJ,iBAAiB;GACjB,qBAAqB;GACrB,UAAU;GACV,cAAc,MAAM,aAAa,MAAM,sBAAsB,MAAM;GACnE,kBAAkB,MAAM;GACxB,WAAW,MAAM;GACjB,aAAa,MAAM;GACnB,iBAAiB;GACjB,kBAAkB;GAClB,gBAAgB,MAAM;EACxB,EACF,EACF;EAEA,UAAA,oBAAC,cAAD;GACE,QAAQ;IACN,MAAM;IACN,GAAG;GACL;GAEA,UAAA,oBAACC,MAAD;IACE,WAAW,GAAG,SAAS;KAAE;KAAS;KAAQ;IAAQ,CAAC,GAAG,SAAS;IAC/D,cAAc;IACd,OAAO;IACP,MAAK;IACA;IACO;IACZ,GAAI;GACL,CAAA;EACW,CAAA;CACA,CAAA;AAEpB,CACF;AAEA,OAAK,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullFeatured.mjs","names":["Flexbox"],"sources":["../../src/Mermaid/FullFeatured.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { ChevronDown, ChevronRight } from 'lucide-react';\nimport { memo, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport ActionIcon from '@/ActionIcon';\nimport CopyButton from '@/CopyButton';\nimport { Flexbox } from '@/Flex';\nimport { bodyVariants, headerVariants, variants } from '@/Highlighter/style';\nimport MaterialFileTypeIcon from '@/MaterialFileTypeIcon';\nimport Text from '@/Text';\nimport { stopPropagation } from '@/utils/dom';\n\nimport { type MermaidProps } from './type';\n\nconst MermaidHeaderLanguage = memo(\n ({\n fileName,\n language,\n showLanguage,\n }: {\n fileName?: string;\n language: string;\n showLanguage?: boolean;\n }) => {\n if (!showLanguage) return null;\n\n return (\n <Flexbox\n horizontal\n align={'center'}\n className={'languageTitle'}\n flex={1}\n gap={4}\n justify={'flex-start'}\n paddingInline={8}\n >\n <MaterialFileTypeIcon\n fallbackUnknownType={false}\n filename={fileName || language}\n size={18}\n type={'file'}\n variant={'raw'}\n />\n\n <Text ellipsis fontSize={13}>\n {fileName || 'Mermaid'}\n </Text>\n </Flexbox>\n );\n },\n (prev, next) =>\n prev.fileName === next.fileName &&\n prev.language === next.language &&\n prev.showLanguage === next.showLanguage,\n);\n\nexport interface MermaidFullFeaturedProps extends Omit<MermaidProps, 'children'> {\n children: ReactNode;\n content: string;\n}\n\nexport const MermaidFullFeatured = memo<MermaidFullFeaturedProps>(\n ({\n showLanguage,\n styles: customStyles,\n classNames,\n content,\n children,\n className,\n copyable,\n actionsRender,\n style,\n variant,\n shadow,\n language = 'mermaid',\n fileName,\n defaultExpand = true,\n ...rest\n }) => {\n const [expand, setExpand] = useState(defaultExpand);\n const contentRef = useRef(content);\n\n useEffect(() => {\n contentRef.current = content;\n }, [content]);\n\n const getContent = useCallback(() => contentRef.current, []);\n\n const originalActions = useMemo(() => {\n if (!copyable) return null;\n return <CopyButton content={getContent} size={'small'} />;\n }, [copyable, getContent]);\n\n const actions = useMemo(() => {\n if (!actionsRender) return originalActions;\n return actionsRender({\n actionIconSize: 'small',\n content,\n getContent,\n originalNode: originalActions,\n });\n }, [actionsRender, content, getContent, originalActions]);\n\n const handleToggleExpand = useCallback(() => {\n setExpand((prev) => !prev);\n }, []);\n\n return (\n <Flexbox\n className={cx(variants({ shadow, variant }), className)}\n data-code-type=\"mermaid\"\n style={style}\n {...rest}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={cx(headerVariants({ variant }), classNames?.header)}\n justify={'space-between'}\n style={customStyles?.header}\n onClick={handleToggleExpand}\n >\n <MermaidHeaderLanguage\n fileName={fileName}\n language={language}\n showLanguage={showLanguage}\n />\n <Flexbox horizontal align={'center'} flex={'none'} gap={4} onClick={stopPropagation}>\n <Flexbox horizontal align={'center'} className={'panel-actions'} flex={'none'} gap={4}>\n {actions}\n </Flexbox>\n <ActionIcon\n icon={expand ? ChevronDown : ChevronRight}\n size={'small'}\n onClick={handleToggleExpand}\n />\n </Flexbox>\n </Flexbox>\n <Flexbox\n className={cx(bodyVariants({ expand }), classNames?.body)}\n style={customStyles?.body}\n >\n {children}\n </Flexbox>\n </Flexbox>\n );\n },\n);\n\nexport default MermaidFullFeatured;\n"],"mappings":";;;;;;;;;;;;;AAgBA,MAAM,wBAAwB,MAC3B,EACC,UACA,UACA,mBAKI;CACJ,IAAI,CAAC,cAAc,OAAO;CAE1B,OACE,qBAACA,mBAAD;EACE,YAAA;EACA,OAAO;EACP,WAAW;EACX,MAAM;EACN,KAAK;EACL,SAAS;EACT,eAAe;
|
|
1
|
+
{"version":3,"file":"FullFeatured.mjs","names":["Flexbox"],"sources":["../../src/Mermaid/FullFeatured.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { ChevronDown, ChevronRight } from 'lucide-react';\nimport { memo, type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport ActionIcon from '@/ActionIcon';\nimport CopyButton from '@/CopyButton';\nimport { Flexbox } from '@/Flex';\nimport { bodyVariants, headerVariants, variants } from '@/Highlighter/style';\nimport MaterialFileTypeIcon from '@/MaterialFileTypeIcon';\nimport Text from '@/Text';\nimport { stopPropagation } from '@/utils/dom';\n\nimport { type MermaidProps } from './type';\n\nconst MermaidHeaderLanguage = memo(\n ({\n fileName,\n language,\n showLanguage,\n }: {\n fileName?: string;\n language: string;\n showLanguage?: boolean;\n }) => {\n if (!showLanguage) return null;\n\n return (\n <Flexbox\n horizontal\n align={'center'}\n className={'languageTitle'}\n flex={1}\n gap={4}\n justify={'flex-start'}\n paddingInline={8}\n >\n <MaterialFileTypeIcon\n fallbackUnknownType={false}\n filename={fileName || language}\n size={18}\n type={'file'}\n variant={'raw'}\n />\n\n <Text ellipsis fontSize={13}>\n {fileName || 'Mermaid'}\n </Text>\n </Flexbox>\n );\n },\n (prev, next) =>\n prev.fileName === next.fileName &&\n prev.language === next.language &&\n prev.showLanguage === next.showLanguage,\n);\n\nexport interface MermaidFullFeaturedProps extends Omit<MermaidProps, 'children'> {\n children: ReactNode;\n content: string;\n}\n\nexport const MermaidFullFeatured = memo<MermaidFullFeaturedProps>(\n ({\n showLanguage,\n styles: customStyles,\n classNames,\n content,\n children,\n className,\n copyable,\n actionsRender,\n style,\n variant,\n shadow,\n language = 'mermaid',\n fileName,\n defaultExpand = true,\n ...rest\n }) => {\n const [expand, setExpand] = useState(defaultExpand);\n const contentRef = useRef(content);\n\n useEffect(() => {\n contentRef.current = content;\n }, [content]);\n\n const getContent = useCallback(() => contentRef.current, []);\n\n const originalActions = useMemo(() => {\n if (!copyable) return null;\n return <CopyButton content={getContent} size={'small'} />;\n }, [copyable, getContent]);\n\n const actions = useMemo(() => {\n if (!actionsRender) return originalActions;\n return actionsRender({\n actionIconSize: 'small',\n content,\n getContent,\n originalNode: originalActions,\n });\n }, [actionsRender, content, getContent, originalActions]);\n\n const handleToggleExpand = useCallback(() => {\n setExpand((prev) => !prev);\n }, []);\n\n return (\n <Flexbox\n className={cx(variants({ shadow, variant }), className)}\n data-code-type=\"mermaid\"\n style={style}\n {...rest}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={cx(headerVariants({ variant }), classNames?.header)}\n justify={'space-between'}\n style={customStyles?.header}\n onClick={handleToggleExpand}\n >\n <MermaidHeaderLanguage\n fileName={fileName}\n language={language}\n showLanguage={showLanguage}\n />\n <Flexbox horizontal align={'center'} flex={'none'} gap={4} onClick={stopPropagation}>\n <Flexbox horizontal align={'center'} className={'panel-actions'} flex={'none'} gap={4}>\n {actions}\n </Flexbox>\n <ActionIcon\n icon={expand ? ChevronDown : ChevronRight}\n size={'small'}\n onClick={handleToggleExpand}\n />\n </Flexbox>\n </Flexbox>\n <Flexbox\n className={cx(bodyVariants({ expand }), classNames?.body)}\n style={customStyles?.body}\n >\n {children}\n </Flexbox>\n </Flexbox>\n );\n },\n);\n\nexport default MermaidFullFeatured;\n"],"mappings":";;;;;;;;;;;;;AAgBA,MAAM,wBAAwB,MAC3B,EACC,UACA,UACA,mBAKI;CACJ,IAAI,CAAC,cAAc,OAAO;CAE1B,OACE,qBAACA,mBAAD;EACE,YAAA;EACA,OAAO;EACP,WAAW;EACX,MAAM;EACN,KAAK;EACL,SAAS;EACT,eAAe;EAPjB,UAAA,CASE,oBAAC,sBAAD;GACE,qBAAqB;GACrB,UAAU,YAAY;GACtB,MAAM;GACN,MAAM;GACN,SAAS;EACV,CAAA,GAED,oBAAC,MAAD;GAAM,UAAA;GAAS,UAAU;GACtB,UAAA,YAAY;EACT,CAAA,CACC;;AAEb,IACC,MAAM,SACL,KAAK,aAAa,KAAK,YACvB,KAAK,aAAa,KAAK,YACvB,KAAK,iBAAiB,KAAK,YAC/B;AAOA,MAAa,sBAAsB,MAChC,EACC,cACA,QAAQ,cACR,YACA,SACA,UACA,WACA,UACA,eACA,OACA,SACA,QACA,WAAW,WACX,UACA,gBAAgB,MAChB,GAAG,WACC;CACJ,MAAM,CAAC,QAAQ,aAAa,SAAS,aAAa;CAClD,MAAM,aAAa,OAAO,OAAO;CAEjC,gBAAgB;EACd,WAAW,UAAU;CACvB,GAAG,CAAC,OAAO,CAAC;CAEZ,MAAM,aAAa,kBAAkB,WAAW,SAAS,CAAC,CAAC;CAE3D,MAAM,kBAAkB,cAAc;EACpC,IAAI,CAAC,UAAU,OAAO;EACtB,OAAO,oBAAC,YAAD;GAAY,SAAS;GAAY,MAAM;EAAU,CAAA;CAC1D,GAAG,CAAC,UAAU,UAAU,CAAC;CAEzB,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB,gBAAgB;GAChB;GACA;GACA,cAAc;EAChB,CAAC;CACH,GAAG;EAAC;EAAe;EAAS;EAAY;CAAe,CAAC;CAExD,MAAM,qBAAqB,kBAAkB;EAC3C,WAAW,SAAS,CAAC,IAAI;CAC3B,GAAG,CAAC,CAAC;CAEL,OACE,qBAACA,mBAAD;EACE,WAAW,GAAG,SAAS;GAAE;GAAQ;EAAQ,CAAC,GAAG,SAAS;EACtD,kBAAe;EACR;EACP,GAAI;EAJN,UAAA,CAME,qBAACA,mBAAD;GACE,YAAA;GACA,OAAO;GACP,WAAW,GAAG,eAAe,EAAE,QAAQ,CAAC,GAAG,YAAY,MAAM;GAC7D,SAAS;GACT,OAAO,cAAc;GACrB,SAAS;GANX,UAAA,CAQE,oBAAC,uBAAD;IACY;IACA;IACI;GACf,CAAA,GACD,qBAACA,mBAAD;IAAS,YAAA;IAAW,OAAO;IAAU,MAAM;IAAQ,KAAK;IAAG,SAAS;IAApE,UAAA,CACE,oBAACA,mBAAD;KAAS,YAAA;KAAW,OAAO;KAAU,WAAW;KAAiB,MAAM;KAAQ,KAAK;KACjF,UAAA;IACM,CAAA,GACT,oBAAC,YAAD;KACE,MAAM,SAAS,cAAc;KAC7B,MAAM;KACN,SAAS;IACV,CAAA,CACM;GACF,CAAA,CAAA;EACT,CAAA,GAAA,oBAACA,mBAAD;GACE,WAAW,GAAG,aAAa,EAAE,OAAO,CAAC,GAAG,YAAY,IAAI;GACxD,OAAO,cAAc;GAEpB;EACM,CAAA,CACF;;AAEb,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mermaid.mjs","names":["FullFeatured","Flexbox"],"sources":["../../src/Mermaid/Mermaid.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { memo, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport CopyButton from '@/CopyButton';\nimport { Flexbox } from '@/Flex';\nimport { styles, variants } from '@/Highlighter/style';\nimport Tag from '@/Tag';\n\nimport FullFeatured from './FullFeatured';\nimport SyntaxMermaid from './SyntaxMermaid';\nimport type { MermaidProps } from './type';\n\nconst Mermaid = memo<MermaidProps>(\n ({\n actionIconSize,\n animated,\n bodyRender,\n children,\n classNames,\n className,\n copyable = true,\n defaultExpand = true,\n fileName,\n fullFeatured,\n language = 'mermaid',\n actionsRender,\n shadow,\n showLanguage = true,\n style,\n styles: customStyles,\n theme,\n variant = 'filled',\n ...rest\n }) => {\n const tirmedChildren = children.trim();\n const copyContentRef = useRef(tirmedChildren);\n\n useEffect(() => {\n copyContentRef.current = tirmedChildren;\n }, [tirmedChildren]);\n\n const getCopyContent = useCallback(() => copyContentRef.current, []);\n\n const originalActions = useMemo(() => {\n if (!copyable) return null;\n return (\n <CopyButton content={getCopyContent} size={actionIconSize || { blockSize: 28, size: 16 }} />\n );\n }, [actionIconSize, copyable, getCopyContent]);\n\n const actions = useMemo(() => {\n if (!actionsRender) return originalActions;\n return actionsRender({\n actionIconSize,\n content: tirmedChildren,\n getContent: getCopyContent,\n originalNode: originalActions,\n });\n }, [actionIconSize, actionsRender, getCopyContent, originalActions, tirmedChildren]);\n\n const defaultBody = useMemo(\n () => (\n <SyntaxMermaid\n animated={animated}\n className={classNames?.content}\n style={customStyles?.content}\n theme={theme}\n variant={variant}\n >\n {tirmedChildren}\n </SyntaxMermaid>\n ),\n [animated, theme, tirmedChildren, variant, classNames?.content, customStyles?.content],\n );\n\n const body = useMemo(() => {\n if (!bodyRender) return defaultBody;\n return bodyRender({ content: tirmedChildren, originalNode: defaultBody });\n }, [bodyRender, defaultBody, tirmedChildren]);\n\n if (fullFeatured)\n return (\n <FullFeatured\n actionsRender={actionsRender}\n className={className}\n classNames={classNames}\n content={tirmedChildren}\n copyable={copyable}\n defaultExpand={defaultExpand}\n fileName={fileName}\n language={language}\n shadow={shadow}\n showLanguage={showLanguage}\n style={style}\n styles={customStyles}\n variant={variant}\n {...rest}\n >\n {body}\n </FullFeatured>\n );\n\n return (\n <div\n className={cx(variants({ shadow, variant }), className)}\n data-code-type=\"mermaid\"\n style={style}\n {...rest}\n >\n <Flexbox horizontal align={'center'} className={styles.actions} flex={'none'} gap={4}>\n {actions}\n </Flexbox>\n {showLanguage && <Tag className={styles.lang}>{language.toLowerCase()}</Tag>}\n {body}\n </div>\n );\n },\n);\n\nMermaid.displayName = 'Mermaid';\n\nexport default Mermaid;\n\nexport { type MermaidProps } from './type';\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,UAAU,MACb,EACC,gBACA,UACA,YACA,UACA,YACA,WACA,WAAW,MACX,gBAAgB,MAChB,UACA,cACA,WAAW,WACX,eACA,QACA,eAAe,MACf,OACA,QAAQ,cACR,OACA,UAAU,UACV,GAAG,WACC;CACJ,MAAM,iBAAiB,SAAS,KAAK;CACrC,MAAM,iBAAiB,OAAO,cAAc;CAE5C,gBAAgB;EACd,eAAe,UAAU;CAC3B,GAAG,CAAC,cAAc,CAAC;CAEnB,MAAM,iBAAiB,kBAAkB,eAAe,SAAS,CAAC,CAAC;CAEnE,MAAM,kBAAkB,cAAc;EACpC,IAAI,CAAC,UAAU,OAAO;EACtB,OACE,oBAAC,YAAD;GAAY,SAAS;GAAgB,MAAM,kBAAkB;IAAE,WAAW;IAAI,MAAM;GAAG;EAAI,CAAA;CAE/F,GAAG;EAAC;EAAgB;EAAU;CAAc,CAAC;CAE7C,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB;GACA,SAAS;GACT,YAAY;GACZ,cAAc;EAChB,CAAC;CACH,GAAG;EAAC;EAAgB;EAAe;EAAgB;EAAiB;CAAc,CAAC;CAEnF,MAAM,cAAc,cAEhB,oBAAC,eAAD;EACY;EACV,WAAW,YAAY;EACvB,OAAO,cAAc;EACd;EACE;
|
|
1
|
+
{"version":3,"file":"Mermaid.mjs","names":["FullFeatured","Flexbox"],"sources":["../../src/Mermaid/Mermaid.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport { memo, useCallback, useEffect, useMemo, useRef } from 'react';\n\nimport CopyButton from '@/CopyButton';\nimport { Flexbox } from '@/Flex';\nimport { styles, variants } from '@/Highlighter/style';\nimport Tag from '@/Tag';\n\nimport FullFeatured from './FullFeatured';\nimport SyntaxMermaid from './SyntaxMermaid';\nimport type { MermaidProps } from './type';\n\nconst Mermaid = memo<MermaidProps>(\n ({\n actionIconSize,\n animated,\n bodyRender,\n children,\n classNames,\n className,\n copyable = true,\n defaultExpand = true,\n fileName,\n fullFeatured,\n language = 'mermaid',\n actionsRender,\n shadow,\n showLanguage = true,\n style,\n styles: customStyles,\n theme,\n variant = 'filled',\n ...rest\n }) => {\n const tirmedChildren = children.trim();\n const copyContentRef = useRef(tirmedChildren);\n\n useEffect(() => {\n copyContentRef.current = tirmedChildren;\n }, [tirmedChildren]);\n\n const getCopyContent = useCallback(() => copyContentRef.current, []);\n\n const originalActions = useMemo(() => {\n if (!copyable) return null;\n return (\n <CopyButton content={getCopyContent} size={actionIconSize || { blockSize: 28, size: 16 }} />\n );\n }, [actionIconSize, copyable, getCopyContent]);\n\n const actions = useMemo(() => {\n if (!actionsRender) return originalActions;\n return actionsRender({\n actionIconSize,\n content: tirmedChildren,\n getContent: getCopyContent,\n originalNode: originalActions,\n });\n }, [actionIconSize, actionsRender, getCopyContent, originalActions, tirmedChildren]);\n\n const defaultBody = useMemo(\n () => (\n <SyntaxMermaid\n animated={animated}\n className={classNames?.content}\n style={customStyles?.content}\n theme={theme}\n variant={variant}\n >\n {tirmedChildren}\n </SyntaxMermaid>\n ),\n [animated, theme, tirmedChildren, variant, classNames?.content, customStyles?.content],\n );\n\n const body = useMemo(() => {\n if (!bodyRender) return defaultBody;\n return bodyRender({ content: tirmedChildren, originalNode: defaultBody });\n }, [bodyRender, defaultBody, tirmedChildren]);\n\n if (fullFeatured)\n return (\n <FullFeatured\n actionsRender={actionsRender}\n className={className}\n classNames={classNames}\n content={tirmedChildren}\n copyable={copyable}\n defaultExpand={defaultExpand}\n fileName={fileName}\n language={language}\n shadow={shadow}\n showLanguage={showLanguage}\n style={style}\n styles={customStyles}\n variant={variant}\n {...rest}\n >\n {body}\n </FullFeatured>\n );\n\n return (\n <div\n className={cx(variants({ shadow, variant }), className)}\n data-code-type=\"mermaid\"\n style={style}\n {...rest}\n >\n <Flexbox horizontal align={'center'} className={styles.actions} flex={'none'} gap={4}>\n {actions}\n </Flexbox>\n {showLanguage && <Tag className={styles.lang}>{language.toLowerCase()}</Tag>}\n {body}\n </div>\n );\n },\n);\n\nMermaid.displayName = 'Mermaid';\n\nexport default Mermaid;\n\nexport { type MermaidProps } from './type';\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,UAAU,MACb,EACC,gBACA,UACA,YACA,UACA,YACA,WACA,WAAW,MACX,gBAAgB,MAChB,UACA,cACA,WAAW,WACX,eACA,QACA,eAAe,MACf,OACA,QAAQ,cACR,OACA,UAAU,UACV,GAAG,WACC;CACJ,MAAM,iBAAiB,SAAS,KAAK;CACrC,MAAM,iBAAiB,OAAO,cAAc;CAE5C,gBAAgB;EACd,eAAe,UAAU;CAC3B,GAAG,CAAC,cAAc,CAAC;CAEnB,MAAM,iBAAiB,kBAAkB,eAAe,SAAS,CAAC,CAAC;CAEnE,MAAM,kBAAkB,cAAc;EACpC,IAAI,CAAC,UAAU,OAAO;EACtB,OACE,oBAAC,YAAD;GAAY,SAAS;GAAgB,MAAM,kBAAkB;IAAE,WAAW;IAAI,MAAM;GAAG;EAAI,CAAA;CAE/F,GAAG;EAAC;EAAgB;EAAU;CAAc,CAAC;CAE7C,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB;GACA,SAAS;GACT,YAAY;GACZ,cAAc;EAChB,CAAC;CACH,GAAG;EAAC;EAAgB;EAAe;EAAgB;EAAiB;CAAc,CAAC;CAEnF,MAAM,cAAc,cAEhB,oBAAC,eAAD;EACY;EACV,WAAW,YAAY;EACvB,OAAO,cAAc;EACd;EACE;EAER,UAAA;CACY,CAAA,GAEjB;EAAC;EAAU;EAAO;EAAgB;EAAS,YAAY;EAAS,cAAc;CAAO,CACvF;CAEA,MAAM,OAAO,cAAc;EACzB,IAAI,CAAC,YAAY,OAAO;EACxB,OAAO,WAAW;GAAE,SAAS;GAAgB,cAAc;EAAY,CAAC;CAC1E,GAAG;EAAC;EAAY;EAAa;CAAc,CAAC;CAE5C,IAAI,cACF,OACE,oBAACA,qBAAD;EACiB;EACJ;EACC;EACZ,SAAS;EACC;EACK;EACL;EACA;EACF;EACM;EACP;EACP,QAAQ;EACC;EACT,GAAI;EAEH,UAAA;CACW,CAAA;CAGlB,OACE,qBAAC,OAAD;EACE,WAAW,GAAG,SAAS;GAAE;GAAQ;EAAQ,CAAC,GAAG,SAAS;EACtD,kBAAe;EACR;EACP,GAAI;EAJN,UAAA;GAME,oBAACC,mBAAD;IAAS,YAAA;IAAW,OAAO;IAAU,WAAW,OAAO;IAAS,MAAM;IAAQ,KAAK;IAChF,UAAA;GACM,CAAA;GACR,gBAAgB,oBAAC,KAAD;IAAK,WAAW,OAAO;IAAO,UAAA,SAAS,YAAY;GAAO,CAAA;GAC1E;EACE;;AAET,CACF;AAEA,QAAQ,cAAc"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import FlexBasic_default from "../../Flex/FlexBasic.mjs";
|
|
3
|
+
import Text from "../../Text/Text.mjs";
|
|
4
|
+
import { memo } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/Mermaid/SyntaxMermaid/MermaidFallback.tsx
|
|
7
|
+
const MermaidFallback = memo(({ children, className, message, style }) => /* @__PURE__ */ jsx("div", {
|
|
8
|
+
className,
|
|
9
|
+
style,
|
|
10
|
+
children: /* @__PURE__ */ jsxs(FlexBasic_default, {
|
|
11
|
+
gap: 8,
|
|
12
|
+
padding: 16,
|
|
13
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
14
|
+
fontSize: 12,
|
|
15
|
+
type: "secondary",
|
|
16
|
+
children: message
|
|
17
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
18
|
+
code: true,
|
|
19
|
+
as: "pre",
|
|
20
|
+
fontSize: 12,
|
|
21
|
+
style: {
|
|
22
|
+
margin: 0,
|
|
23
|
+
overflowX: "auto",
|
|
24
|
+
whiteSpace: "pre-wrap",
|
|
25
|
+
wordBreak: "break-word"
|
|
26
|
+
},
|
|
27
|
+
children
|
|
28
|
+
})]
|
|
29
|
+
})
|
|
30
|
+
}));
|
|
31
|
+
MermaidFallback.displayName = "MermaidFallback";
|
|
32
|
+
//#endregion
|
|
33
|
+
export { MermaidFallback as default };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=MermaidFallback.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MermaidFallback.mjs","names":["Flexbox"],"sources":["../../../src/Mermaid/SyntaxMermaid/MermaidFallback.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport Text from '@/Text';\n\nimport { type SyntaxMermaidProps } from '../type';\n\ninterface MermaidFallbackProps {\n children: string;\n className?: string;\n message: string;\n style?: SyntaxMermaidProps['style'];\n}\n\nconst MermaidFallback = memo<MermaidFallbackProps>(({ children, className, message, style }) => (\n <div className={className} style={style}>\n <Flexbox gap={8} padding={16}>\n <Text fontSize={12} type={'secondary'}>\n {message}\n </Text>\n <Text\n code\n as={'pre'}\n fontSize={12}\n style={{ margin: 0, overflowX: 'auto', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}\n >\n {children}\n </Text>\n </Flexbox>\n </div>\n));\n\nMermaidFallback.displayName = 'MermaidFallback';\n\nexport default MermaidFallback;\n"],"mappings":";;;;;;AAgBA,MAAM,kBAAkB,MAA4B,EAAE,UAAU,WAAW,SAAS,YAClF,oBAAC,OAAD;CAAgB;CAAkB;CAChC,UAAA,qBAACA,mBAAD;EAAS,KAAK;EAAG,SAAS;EAA1B,UAAA,CACE,oBAAC,MAAD;GAAM,UAAU;GAAI,MAAM;GACvB,UAAA;EACG,CAAA,GACN,oBAAC,MAAD;GACE,MAAA;GACA,IAAI;GACJ,UAAU;GACV,OAAO;IAAE,QAAQ;IAAG,WAAW;IAAQ,YAAY;IAAY,WAAW;GAAa;GAEtF;EACG,CAAA,CACC;;AACN,CAAA,CACN;AAED,gBAAgB,cAAc"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { toStandaloneSvgString } from "./prepareInlineSvg.mjs";
|
|
3
|
+
import { prepareMermaidSvgString } from "./prepareMermaidSvg.mjs";
|
|
4
|
+
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Image } from "antd";
|
|
7
|
+
//#region src/Mermaid/SyntaxMermaid/MermaidSvg.tsx
|
|
8
|
+
const MermaidSvg = memo(({ className, ref, style, svg }) => {
|
|
9
|
+
const containerRef = useRef(null);
|
|
10
|
+
const [previewUrl, setPreviewUrl] = useState();
|
|
11
|
+
const [open, setOpen] = useState(false);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
return () => {
|
|
14
|
+
if (previewUrl) URL.revokeObjectURL(previewUrl);
|
|
15
|
+
};
|
|
16
|
+
}, [previewUrl]);
|
|
17
|
+
const handleOpen = useCallback(() => {
|
|
18
|
+
const element = containerRef.current?.querySelector("svg");
|
|
19
|
+
if (!element) return;
|
|
20
|
+
const standalone = prepareMermaidSvgString(toStandaloneSvgString(element));
|
|
21
|
+
setPreviewUrl((previous) => {
|
|
22
|
+
if (previous) URL.revokeObjectURL(previous);
|
|
23
|
+
return URL.createObjectURL(new Blob([standalone], { type: "image/svg+xml" }));
|
|
24
|
+
});
|
|
25
|
+
setOpen(true);
|
|
26
|
+
}, []);
|
|
27
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
28
|
+
className,
|
|
29
|
+
ref,
|
|
30
|
+
style,
|
|
31
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
32
|
+
dangerouslySetInnerHTML: { __html: svg },
|
|
33
|
+
ref: containerRef,
|
|
34
|
+
style: { cursor: "zoom-in" },
|
|
35
|
+
onClick: handleOpen
|
|
36
|
+
}), previewUrl && /* @__PURE__ */ jsx(Image, {
|
|
37
|
+
preview: {
|
|
38
|
+
onVisibleChange: setOpen,
|
|
39
|
+
src: previewUrl,
|
|
40
|
+
visible: open
|
|
41
|
+
},
|
|
42
|
+
src: previewUrl,
|
|
43
|
+
style: { display: "none" },
|
|
44
|
+
wrapperStyle: { display: "none" }
|
|
45
|
+
})]
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
MermaidSvg.displayName = "MermaidSvg";
|
|
49
|
+
//#endregion
|
|
50
|
+
export { MermaidSvg as default };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=MermaidSvg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MermaidSvg.mjs","names":["AntImage"],"sources":["../../../src/Mermaid/SyntaxMermaid/MermaidSvg.tsx"],"sourcesContent":["'use client';\n\nimport { Image as AntImage } from 'antd';\nimport { memo, type Ref, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { toStandaloneSvgString } from './prepareInlineSvg';\nimport { prepareMermaidSvgString } from './prepareMermaidSvg';\n\ninterface MermaidSvgProps {\n className?: string;\n ref?: Ref<HTMLDivElement>;\n style?: React.CSSProperties;\n svg: string;\n}\n\nconst MermaidSvg = memo<MermaidSvgProps>(({ className, ref, style, svg }) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [previewUrl, setPreviewUrl] = useState<string>();\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n return () => {\n if (previewUrl) URL.revokeObjectURL(previewUrl);\n };\n }, [previewUrl]);\n\n // The preview copy is only built on demand: it has to bake in the resolved\n // CSS variables and be XML-well-formed, neither of which the inline copy needs.\n const handleOpen = useCallback(() => {\n const element = containerRef.current?.querySelector('svg');\n if (!element) return;\n\n const standalone = prepareMermaidSvgString(toStandaloneSvgString(element));\n setPreviewUrl((previous) => {\n if (previous) URL.revokeObjectURL(previous);\n return URL.createObjectURL(new Blob([standalone], { type: 'image/svg+xml' }));\n });\n setOpen(true);\n }, []);\n\n return (\n <div className={className} ref={ref} style={style}>\n <div\n dangerouslySetInnerHTML={{ __html: svg }}\n ref={containerRef}\n style={{ cursor: 'zoom-in' }}\n onClick={handleOpen}\n />\n {previewUrl && (\n <AntImage\n preview={{ onVisibleChange: setOpen, src: previewUrl, visible: open }}\n src={previewUrl}\n style={{ display: 'none' }}\n wrapperStyle={{ display: 'none' }}\n />\n )}\n </div>\n );\n});\n\nMermaidSvg.displayName = 'MermaidSvg';\n\nexport default MermaidSvg;\n"],"mappings":";;;;;;;AAeA,MAAM,aAAa,MAAuB,EAAE,WAAW,KAAK,OAAO,UAAU;CAC3E,MAAM,eAAe,OAAuB,IAAI;CAChD,MAAM,CAAC,YAAY,iBAAiB,SAAiB;CACrD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CAEtC,gBAAgB;EACd,aAAa;GACX,IAAI,YAAY,IAAI,gBAAgB,UAAU;EAChD;CACF,GAAG,CAAC,UAAU,CAAC;CAIf,MAAM,aAAa,kBAAkB;EACnC,MAAM,UAAU,aAAa,SAAS,cAAc,KAAK;EACzD,IAAI,CAAC,SAAS;EAEd,MAAM,aAAa,wBAAwB,sBAAsB,OAAO,CAAC;EACzE,eAAe,aAAa;GAC1B,IAAI,UAAU,IAAI,gBAAgB,QAAQ;GAC1C,OAAO,IAAI,gBAAgB,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,gBAAgB,CAAC,CAAC;EAC9E,CAAC;EACD,QAAQ,IAAI;CACd,GAAG,CAAC,CAAC;CAEL,OACE,qBAAC,OAAD;EAAgB;EAAgB;EAAY;EAA5C,UAAA,CACE,oBAAC,OAAD;GACE,yBAAyB,EAAE,QAAQ,IAAI;GACvC,KAAK;GACL,OAAO,EAAE,QAAQ,UAAU;GAC3B,SAAS;EACV,CAAA,GACA,cACC,oBAACA,OAAD;GACE,SAAS;IAAE,iBAAiB;IAAS,KAAK;IAAY,SAAS;GAAK;GACpE,KAAK;GACL,OAAO,EAAE,SAAS,OAAO;GACzB,cAAc,EAAE,SAAS,OAAO;EACjC,CAAA,CAEA;;AAET,CAAC;AAED,WAAW,cAAc"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import Image from "../../Image/index.mjs";
|
|
3
2
|
import { mermaidThemes } from "../const.mjs";
|
|
4
3
|
import { useMermaid } from "../../hooks/useMermaid.mjs";
|
|
5
|
-
import
|
|
4
|
+
import MermaidFallback from "./MermaidFallback.mjs";
|
|
5
|
+
import MermaidSvg from "./MermaidSvg.mjs";
|
|
6
|
+
import { memo, useMemo } from "react";
|
|
6
7
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
-
import { kebabCase } from "es-toolkit/compat";
|
|
8
8
|
//#region src/Mermaid/SyntaxMermaid/StaticMermaid.tsx
|
|
9
9
|
const StaticMermaid = memo(({ children, className, fallbackClassName, ref, style, theme: customTheme, variant }) => {
|
|
10
10
|
const safeChildren = children ?? "";
|
|
@@ -13,36 +13,7 @@ const StaticMermaid = memo(({ children, className, fallbackClassName, ref, style
|
|
|
13
13
|
if (isDefaultTheme) return;
|
|
14
14
|
return mermaidThemes.find((item) => item.id === customTheme)?.background;
|
|
15
15
|
}, [isDefaultTheme, customTheme]);
|
|
16
|
-
const
|
|
17
|
-
id: kebabCase(`mermaid-${useId()}`),
|
|
18
|
-
theme: isDefaultTheme ? void 0 : customTheme
|
|
19
|
-
});
|
|
20
|
-
const isLoading = !data;
|
|
21
|
-
const [blobUrl, setBlobUrl] = useState();
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
return () => {
|
|
24
|
-
if (blobUrl) URL.revokeObjectURL(blobUrl);
|
|
25
|
-
};
|
|
26
|
-
}, [blobUrl]);
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
if (isLoading || !data) return;
|
|
29
|
-
let finalSvgString = data;
|
|
30
|
-
if (typeof window !== "undefined" && typeof navigator !== "undefined" && navigator.userAgent.includes("Firefox")) {
|
|
31
|
-
const svgDoc = new DOMParser().parseFromString(data, "image/svg+xml");
|
|
32
|
-
const svgElement = svgDoc.documentElement;
|
|
33
|
-
if (svgElement && svgElement.hasAttribute("viewBox")) {
|
|
34
|
-
const viewBoxParts = svgElement.getAttribute("viewBox").split(" ");
|
|
35
|
-
if (Array.isArray(viewBoxParts) && viewBoxParts.length === 4) {
|
|
36
|
-
svgElement.setAttribute("width", viewBoxParts[2]);
|
|
37
|
-
svgElement.setAttribute("height", viewBoxParts[3]);
|
|
38
|
-
}
|
|
39
|
-
finalSvgString = new XMLSerializer().serializeToString(svgDoc);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
const svgBlob = new Blob([finalSvgString], { type: "image/svg+xml" });
|
|
43
|
-
const url = URL.createObjectURL(svgBlob);
|
|
44
|
-
setBlobUrl(url);
|
|
45
|
-
}, [isLoading, data]);
|
|
16
|
+
const { svg, error, loading } = useMermaid(safeChildren, { theme: isDefaultTheme ? void 0 : customTheme });
|
|
46
17
|
const containerStyle = {
|
|
47
18
|
background: variant === "filled" ? background : void 0,
|
|
48
19
|
margin: 0,
|
|
@@ -52,7 +23,13 @@ const StaticMermaid = memo(({ children, className, fallbackClassName, ref, style
|
|
|
52
23
|
width: "100%",
|
|
53
24
|
...style
|
|
54
25
|
};
|
|
55
|
-
if (!
|
|
26
|
+
if (error && !loading) return /* @__PURE__ */ jsx(MermaidFallback, {
|
|
27
|
+
className: fallbackClassName,
|
|
28
|
+
message: error,
|
|
29
|
+
style,
|
|
30
|
+
children: safeChildren
|
|
31
|
+
});
|
|
32
|
+
if (!svg) return /* @__PURE__ */ jsx("div", {
|
|
56
33
|
className: fallbackClassName,
|
|
57
34
|
style,
|
|
58
35
|
children: /* @__PURE__ */ jsx("div", {
|
|
@@ -60,17 +37,11 @@ const StaticMermaid = memo(({ children, className, fallbackClassName, ref, style
|
|
|
60
37
|
children: "Loading..."
|
|
61
38
|
})
|
|
62
39
|
});
|
|
63
|
-
return /* @__PURE__ */ jsx(
|
|
64
|
-
alt: "mermaid",
|
|
40
|
+
return /* @__PURE__ */ jsx(MermaidSvg, {
|
|
65
41
|
className,
|
|
66
|
-
maxHeight: 480,
|
|
67
|
-
minWidth: 300,
|
|
68
|
-
objectFit: "contain",
|
|
69
42
|
ref,
|
|
70
|
-
src: blobUrl,
|
|
71
43
|
style: containerStyle,
|
|
72
|
-
|
|
73
|
-
width: "100%"
|
|
44
|
+
svg
|
|
74
45
|
});
|
|
75
46
|
});
|
|
76
47
|
StaticMermaid.displayName = "StaticMermaid";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StaticMermaid.mjs","names":[],"sources":["../../../src/Mermaid/SyntaxMermaid/StaticMermaid.tsx"],"sourcesContent":["'use client';\n\nimport {
|
|
1
|
+
{"version":3,"file":"StaticMermaid.mjs","names":[],"sources":["../../../src/Mermaid/SyntaxMermaid/StaticMermaid.tsx"],"sourcesContent":["'use client';\n\nimport { type Ref } from 'react';\nimport { memo, useMemo } from 'react';\n\nimport { useMermaid } from '@/hooks/useMermaid';\n\nimport { mermaidThemes } from '../const';\nimport { type SyntaxMermaidProps } from '../type';\nimport MermaidFallback from './MermaidFallback';\nimport MermaidSvg from './MermaidSvg';\n\ninterface StaticMermaidProps {\n children: string;\n className?: string;\n fallbackClassName?: string;\n ref?: Ref<HTMLDivElement>;\n style?: SyntaxMermaidProps['style'];\n theme?: SyntaxMermaidProps['theme'];\n variant?: SyntaxMermaidProps['variant'];\n}\n\nconst StaticMermaid = memo<StaticMermaidProps>(\n ({ children, className, fallbackClassName, ref, style, theme: customTheme, variant }) => {\n const safeChildren = children ?? '';\n const isDefaultTheme = customTheme === 'lobe-theme' || !customTheme;\n\n const background = useMemo(() => {\n if (isDefaultTheme) return;\n return mermaidThemes.find((item) => item.id === customTheme)?.background;\n }, [isDefaultTheme, customTheme]);\n\n const { svg, error, loading } = useMermaid(safeChildren, {\n theme: isDefaultTheme ? undefined : customTheme,\n });\n\n const containerStyle = {\n background: variant === 'filled' ? background : undefined,\n margin: 0,\n minWidth: 300,\n padding: variant === 'borderless' ? 0 : 16,\n position: 'relative' as const,\n width: '100%',\n ...style,\n };\n\n if (error && !loading) {\n return (\n <MermaidFallback className={fallbackClassName} message={error} style={style}>\n {safeChildren}\n </MermaidFallback>\n );\n }\n\n if (!svg) {\n return (\n <div className={fallbackClassName} style={style}>\n <div style={{ padding: 16 }}>Loading...</div>\n </div>\n );\n }\n\n return <MermaidSvg className={className} ref={ref} style={containerStyle} svg={svg} />;\n },\n);\n\nStaticMermaid.displayName = 'StaticMermaid';\n\nexport default StaticMermaid;\n"],"mappings":";;;;;;;;AAsBA,MAAM,gBAAgB,MACnB,EAAE,UAAU,WAAW,mBAAmB,KAAK,OAAO,OAAO,aAAa,cAAc;CACvF,MAAM,eAAe,YAAY;CACjC,MAAM,iBAAiB,gBAAgB,gBAAgB,CAAC;CAExD,MAAM,aAAa,cAAc;EAC/B,IAAI,gBAAgB;EACpB,OAAO,cAAc,MAAM,SAAS,KAAK,OAAO,WAAW,CAAC,EAAE;CAChE,GAAG,CAAC,gBAAgB,WAAW,CAAC;CAEhC,MAAM,EAAE,KAAK,OAAO,YAAY,WAAW,cAAc,EACvD,OAAO,iBAAiB,KAAA,IAAY,YACtC,CAAC;CAED,MAAM,iBAAiB;EACrB,YAAY,YAAY,WAAW,aAAa,KAAA;EAChD,QAAQ;EACR,UAAU;EACV,SAAS,YAAY,eAAe,IAAI;EACxC,UAAU;EACV,OAAO;EACP,GAAG;CACL;CAEA,IAAI,SAAS,CAAC,SACZ,OACE,oBAAC,iBAAD;EAAiB,WAAW;EAAmB,SAAS;EAAc;EACnE,UAAA;CACc,CAAA;CAIrB,IAAI,CAAC,KACH,OACE,oBAAC,OAAD;EAAK,WAAW;EAA0B;EACxC,UAAA,oBAAC,OAAD;GAAK,OAAO,EAAE,SAAS,GAAG;GAAG,UAAA;EAAe,CAAA;CACzC,CAAA;CAIT,OAAO,oBAAC,YAAD;EAAuB;EAAgB;EAAK,OAAO;EAAqB;CAAM,CAAA;AACvF,CACF;AAEA,cAAc,cAAc"}
|