@lobehub/ui 5.23.5 → 5.25.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/A/index.mjs +2 -1
- package/es/A/index.mjs.map +1 -1
- package/es/Accordion/Accordion.mjs.map +1 -1
- package/es/Accordion/AccordionItem.mjs +0 -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/ActionIcon/components/utils.mjs +7 -9
- package/es/ActionIcon/components/utils.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 +4 -2
- package/es/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/CodeDiff/CodeDiff.mjs +20 -18
- package/es/CodeDiff/CodeDiff.mjs.map +1 -1
- package/es/CodeDiff/DiffPanel.mjs.map +1 -1
- package/es/CodeDiff/PatchDiff.mjs +18 -16
- package/es/CodeDiff/PatchDiff.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/CopyButton/CopyButton.mjs +2 -1
- package/es/CopyButton/CopyButton.mjs.map +1 -1
- 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 +41 -40
- package/es/Highlighter/LangSelect.mjs.map +1 -1
- package/es/Highlighter/SyntaxHighlighter/StaticRenderer.mjs +2 -1
- package/es/Highlighter/SyntaxHighlighter/StaticRenderer.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 +3 -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/HtmlPreview/const.mjs +1 -1
- package/es/HtmlPreview/const.mjs.map +1 -1
- package/es/Icon/Icon.mjs.map +1 -1
- package/es/Icon/components/utils.mjs +7 -9
- package/es/Icon/components/utils.mjs.map +1 -1
- package/es/Image/Image.mjs.map +1 -1
- package/es/Image/components/Toolbar.mjs +2 -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/Img/index.mjs +2 -1
- package/es/Img/index.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 +2 -1
- package/es/Markdown/SyntaxMarkdown/StreamdownRender.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/style.mjs.map +1 -1
- package/es/Markdown/SyntaxMarkdown/useSmoothStreamContent.mjs +2 -2
- package/es/Markdown/SyntaxMarkdown/useSmoothStreamContent.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 +6 -5
- package/es/Modal/RawModalStackItem.mjs.map +1 -1
- package/es/Modal/imperative.mjs +4 -2
- package/es/Modal/imperative.mjs.map +1 -1
- package/es/Modal/style.mjs.map +1 -1
- package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs +1 -1
- package/es/NeuralNetworkLoading/NeuralNetworkLoading.mjs.map +1 -1
- package/es/ScrollShadow/ScrollShadow.mjs +13 -12
- 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/SkeletonButton.mjs +2 -1
- package/es/Skeleton/SkeletonButton.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 +5 -1
- package/es/SortableList/SortableList.mjs.map +1 -1
- package/es/SortableList/components/SortableItem.mjs.map +1 -1
- package/es/Text/Text.mjs +22 -21
- package/es/Text/Text.mjs.map +1 -1
- package/es/ThemeProvider/ThemeProvider.mjs +4 -3
- 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 +1 -3
- 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/Spotlight/Spotlight.mjs +2 -1
- package/es/awesome/Spotlight/Spotlight.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 +13 -11
- package/es/base-ui/Button/Button.mjs.map +1 -1
- package/es/base-ui/Button/SplitButton.mjs +2 -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/ContextMenuTrigger.mjs +2 -1
- package/es/base-ui/ContextMenu/ContextMenuTrigger.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 +2 -1
- 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/Drawer/Drawer.d.mts +6 -0
- package/es/base-ui/Drawer/Drawer.mjs +152 -0
- package/es/base-ui/Drawer/Drawer.mjs.map +1 -0
- package/es/base-ui/Drawer/DrawerLayerContext.mjs +10 -0
- package/es/base-ui/Drawer/DrawerLayerContext.mjs.map +1 -0
- package/es/base-ui/Drawer/DrawerPushContext.mjs +27 -0
- package/es/base-ui/Drawer/DrawerPushContext.mjs.map +1 -0
- package/es/base-ui/Drawer/atoms.d.mts +58 -0
- package/es/base-ui/Drawer/atoms.mjs +262 -0
- package/es/base-ui/Drawer/atoms.mjs.map +1 -0
- package/es/base-ui/Drawer/constants.d.mts +17 -0
- package/es/base-ui/Drawer/constants.mjs +72 -0
- package/es/base-ui/Drawer/constants.mjs.map +1 -0
- package/es/base-ui/Drawer/index.d.mts +5 -0
- package/es/base-ui/Drawer/style.mjs +295 -0
- package/es/base-ui/Drawer/style.mjs.map +1 -0
- package/es/base-ui/Drawer/type.d.mts +65 -0
- package/es/base-ui/DropdownMenu/DropdownMenu.mjs +2 -1
- package/es/base-ui/DropdownMenu/DropdownMenu.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/atoms.mjs +2 -1
- package/es/base-ui/DropdownMenu/atoms.mjs.map +1 -1
- package/es/base-ui/DropdownMenu/renderItems.mjs +2 -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 +4 -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/Modal/Modal.mjs.map +1 -1
- package/es/base-ui/Modal/atoms.mjs +7 -5
- package/es/base-ui/Modal/atoms.mjs.map +1 -1
- package/es/base-ui/Modal/imperative.mjs +2 -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 +2 -1
- package/es/base-ui/Popover/atoms.mjs.map +1 -1
- package/es/base-ui/Popover/context.mjs +4 -2
- package/es/base-ui/Popover/context.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/atoms.mjs +2 -1
- package/es/base-ui/Select/atoms.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 +7 -2
- package/es/base-ui/index.mjs +5 -2
- package/es/brand/LobeChat/index.mjs +0 -1
- package/es/brand/LobeChat/index.mjs.map +1 -1
- package/es/brand/LobeChatText/index.mjs.map +1 -1
- package/es/brand/LobeHub/index.mjs +0 -1
- package/es/brand/LobeHub/index.mjs.map +1 -1
- package/es/brand/LobeHubText/index.mjs.map +1 -1
- package/es/brand/Logo3d/index.mjs +2 -1
- package/es/brand/Logo3d/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 +5 -4
- 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 +2 -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 +0 -2
- 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 +81 -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":"ScaleRow.mjs","names":["Flexbox"],"sources":["../../../src/color/ColorScales/ScaleRow.tsx"],"sourcesContent":["import { message, Space } from 'antd';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { copyToClipboard } from '@/utils/copyToClipboard';\n\nimport { alphaBg, styles } from './style';\n\nexport interface IScaleRow {\n name: string;\n scale: string[];\n title: 'light' | 'lightA' | 'dark' | 'darkA';\n}\n\nconst ScaleRow = memo<IScaleRow>(({ name, title, scale }) => {\n let style = {};\n let isAlpha = false;\n\n switch (title) {\n case 'lightA': {\n style = { background: alphaBg.light, backgroundColor: '#fff' };\n isAlpha = true;\n break;\n }\n case 'darkA': {\n style = { background: alphaBg.dark, backgroundColor: '#000' };\n isAlpha = true;\n break;\n }\n default: {\n break;\n }\n }\n\n return (\n <Space size={2}>\n <div className={styles.scaleRowTitle} key={title}>\n <div className={styles.text}>{title}</div>\n </div>\n {scale.map((color, index) => {\n if (index === 0 || index === 12) return false;\n\n return (\n <div\n className={styles.scaleBox}\n key={index}\n style={style}\n title={color}\n onClick={async () => {\n const content = `token.${name}${index}${isAlpha ? 'A' : ''} /* ${color} */`;\n\n await copyToClipboard(content);\n message.success(content);\n }}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{ backgroundColor: color }}\n />\n </div>\n );\n })}\n </Space>\n );\n});\n\nexport default ScaleRow;\n"],"mappings":";;;;;;;AAcA,MAAM,WAAW,MAAiB,EAAE,MAAM,OAAO,YAAY;CAC3D,IAAI,QAAQ,CAAC;CACb,IAAI,UAAU;CAEd,QAAQ,OAAR;EACE,KAAK;GACH,QAAQ;IAAE,YAAY,QAAQ;IAAO,iBAAiB;GAAO;GAC7D,UAAU;GACV;EAEF,KAAK;GACH,QAAQ;IAAE,YAAY,QAAQ;IAAM,iBAAiB;GAAO;GAC5D,UAAU;
|
|
1
|
+
{"version":3,"file":"ScaleRow.mjs","names":["Flexbox"],"sources":["../../../src/color/ColorScales/ScaleRow.tsx"],"sourcesContent":["import { message, Space } from 'antd';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { copyToClipboard } from '@/utils/copyToClipboard';\n\nimport { alphaBg, styles } from './style';\n\nexport interface IScaleRow {\n name: string;\n scale: string[];\n title: 'light' | 'lightA' | 'dark' | 'darkA';\n}\n\nconst ScaleRow = memo<IScaleRow>(({ name, title, scale }) => {\n let style = {};\n let isAlpha = false;\n\n switch (title) {\n case 'lightA': {\n style = { background: alphaBg.light, backgroundColor: '#fff' };\n isAlpha = true;\n break;\n }\n case 'darkA': {\n style = { background: alphaBg.dark, backgroundColor: '#000' };\n isAlpha = true;\n break;\n }\n default: {\n break;\n }\n }\n\n return (\n <Space size={2}>\n <div className={styles.scaleRowTitle} key={title}>\n <div className={styles.text}>{title}</div>\n </div>\n {scale.map((color, index) => {\n if (index === 0 || index === 12) return false;\n\n return (\n <div\n className={styles.scaleBox}\n key={index}\n style={style}\n title={color}\n onClick={async () => {\n const content = `token.${name}${index}${isAlpha ? 'A' : ''} /* ${color} */`;\n\n await copyToClipboard(content);\n message.success(content);\n }}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{ backgroundColor: color }}\n />\n </div>\n );\n })}\n </Space>\n );\n});\n\nexport default ScaleRow;\n"],"mappings":";;;;;;;AAcA,MAAM,WAAW,MAAiB,EAAE,MAAM,OAAO,YAAY;CAC3D,IAAI,QAAQ,CAAC;CACb,IAAI,UAAU;CAEd,QAAQ,OAAR;EACE,KAAK;GACH,QAAQ;IAAE,YAAY,QAAQ;IAAO,iBAAiB;GAAO;GAC7D,UAAU;GACV;EAEF,KAAK;GACH,QAAQ;IAAE,YAAY,QAAQ;IAAM,iBAAiB;GAAO;GAC5D,UAAU;CAMd;CAEA,OACE,qBAAC,OAAD;EAAO,MAAM;EAAb,UAAA,CACE,oBAAC,OAAD;GAAK,WAAW,OAAO;GACrB,UAAA,oBAAC,OAAD;IAAK,WAAW,OAAO;IAAO,UAAA;GAAW,CAAA;EACtC,GAFsC,KAEtC,GACJ,MAAM,KAAK,OAAO,UAAU;GAC3B,IAAI,UAAU,KAAK,UAAU,IAAI,OAAO;GAExC,OACE,oBAAC,OAAD;IACE,WAAW,OAAO;IAEX;IACP,OAAO;IACP,SAAS,YAAY;KACnB,MAAM,UAAU,SAAS,OAAO,QAAQ,UAAU,MAAM,GAAG,MAAM,MAAM;KAEvE,MAAM,gBAAgB,OAAO;KAC7B,QAAQ,QAAQ,OAAO;IACzB;IAEA,UAAA,oBAACA,mBAAD;KACE,YAAA;KACA,OAAO;KACP,WAAW,OAAO;KAClB,SAAS;KACT,OAAO,EAAE,iBAAiB,MAAM;IACjC,CAAA;GACE,GAjBE,KAiBF;EAET,CAAC,CACI;;AAEX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["Flexbox"],"sources":["../../../src/color/ColorScales/index.tsx"],"sourcesContent":["'use client';\n\nimport { Space } from 'antd';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\n\nimport type { ColorScaleItem } from '../types';\nimport ScaleRow from './ScaleRow';\nimport { styles } from './style';\n\nexport interface ColorScalesProps {\n /**\n * @description Index of the mid highlight color in the scale\n */\n midHighLight: number;\n /**\n * @description Name of the color scale\n */\n name: string;\n /**\n * @description Color scale item object\n */\n scale: ColorScaleItem;\n}\n\nconst ColorScales = memo<ColorScalesProps>(({ name, scale, midHighLight }) => {\n return (\n <Flexbox horizontal align={'center'} flex={1} justify={'center'}>\n <div style={{ padding: '8px 16px 32px 0' }}>\n <Space direction={'vertical'} size={2}>\n <Space key=\"scale-title\" size={2}>\n <Flexbox horizontal align={'center'} className={styles.scaleRowTitle} key=\"scale-num\" />\n {Array.from({ length: scale.light.length })\n .fill('')\n .map((_, index) => {\n if (index === 0 || index === 12) return false;\n\n const isMidHighlight = midHighLight === index;\n\n return (\n <div className={styles.scaleBox} key={`num${index}`}>\n <div className={styles.scaleBox}>\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{\n fontWeight: isMidHighlight ? 700 : 400,\n opacity: 0.5,\n }}\n >\n {index}\n </Flexbox>\n </div>\n </div>\n );\n })}\n </Space>\n <ScaleRow key=\"light\" name={name} scale={scale.light} title=\"light\" />\n <ScaleRow key=\"lightA\" name={name} scale={scale.lightA} title=\"lightA\" />\n <ScaleRow key=\"dark\" name={name} scale={scale.dark} title=\"dark\" />\n <ScaleRow key=\"darkA\" name={name} scale={scale.darkA} title=\"darkA\" />\n </Space>\n </div>\n </Flexbox>\n );\n});\n\nexport default ColorScales;\n"],"mappings":";;;;;;;;AA0BA,MAAM,cAAc,MAAwB,EAAE,MAAM,OAAO,mBAAmB;CAC5E,OACE,oBAACA,mBAAD;EAAS,YAAA;EAAW,OAAO;EAAU,MAAM;EAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["Flexbox"],"sources":["../../../src/color/ColorScales/index.tsx"],"sourcesContent":["'use client';\n\nimport { Space } from 'antd';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\n\nimport type { ColorScaleItem } from '../types';\nimport ScaleRow from './ScaleRow';\nimport { styles } from './style';\n\nexport interface ColorScalesProps {\n /**\n * @description Index of the mid highlight color in the scale\n */\n midHighLight: number;\n /**\n * @description Name of the color scale\n */\n name: string;\n /**\n * @description Color scale item object\n */\n scale: ColorScaleItem;\n}\n\nconst ColorScales = memo<ColorScalesProps>(({ name, scale, midHighLight }) => {\n return (\n <Flexbox horizontal align={'center'} flex={1} justify={'center'}>\n <div style={{ padding: '8px 16px 32px 0' }}>\n <Space direction={'vertical'} size={2}>\n <Space key=\"scale-title\" size={2}>\n <Flexbox horizontal align={'center'} className={styles.scaleRowTitle} key=\"scale-num\" />\n {Array.from({ length: scale.light.length })\n .fill('')\n .map((_, index) => {\n if (index === 0 || index === 12) return false;\n\n const isMidHighlight = midHighLight === index;\n\n return (\n <div className={styles.scaleBox} key={`num${index}`}>\n <div className={styles.scaleBox}>\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{\n fontWeight: isMidHighlight ? 700 : 400,\n opacity: 0.5,\n }}\n >\n {index}\n </Flexbox>\n </div>\n </div>\n );\n })}\n </Space>\n <ScaleRow key=\"light\" name={name} scale={scale.light} title=\"light\" />\n <ScaleRow key=\"lightA\" name={name} scale={scale.lightA} title=\"lightA\" />\n <ScaleRow key=\"dark\" name={name} scale={scale.dark} title=\"dark\" />\n <ScaleRow key=\"darkA\" name={name} scale={scale.darkA} title=\"darkA\" />\n </Space>\n </div>\n </Flexbox>\n );\n});\n\nexport default ColorScales;\n"],"mappings":";;;;;;;;AA0BA,MAAM,cAAc,MAAwB,EAAE,MAAM,OAAO,mBAAmB;CAC5E,OACE,oBAACA,mBAAD;EAAS,YAAA;EAAW,OAAO;EAAU,MAAM;EAAG,SAAS;EACrD,UAAA,oBAAC,OAAD;GAAK,OAAO,EAAE,SAAS,kBAAkB;GACvC,UAAA,qBAAC,OAAD;IAAO,WAAW;IAAY,MAAM;IAApC,UAAA;KACE,qBAAC,OAAD;MAAyB,MAAM;MAA/B,UAAA,CACE,oBAACA,mBAAD;OAAS,YAAA;OAAW,OAAO;OAAU,WAAW,OAAO;MAAgC,GAAb,WAAa,GACtF,MAAM,KAAK,EAAE,QAAQ,MAAM,MAAM,OAAO,CAAC,CAAC,CACxC,KAAK,EAAE,CAAC,CACR,KAAK,GAAG,UAAU;OACjB,IAAI,UAAU,KAAK,UAAU,IAAI,OAAO;OAExC,MAAM,iBAAiB,iBAAiB;OAExC,OACE,oBAAC,OAAD;QAAK,WAAW,OAAO;QACrB,UAAA,oBAAC,OAAD;SAAK,WAAW,OAAO;SACrB,UAAA,oBAACA,mBAAD;UACE,YAAA;UACA,OAAO;UACP,WAAW,OAAO;UAClB,SAAS;UACT,OAAO;WACL,YAAY,iBAAiB,MAAM;WACnC,SAAS;UACX;UAEC,UAAA;SACM,CAAA;QACN,CAAA;OACF,GAfiC,MAAM,OAevC;MAET,CAAC,CACE;KA5BI,GAAA,aA4BJ;KACP,oBAAC,UAAD;MAA4B;MAAM,OAAO,MAAM;MAAO,OAAM;KAAS,GAAvD,OAAuD;KACrE,oBAAC,UAAD;MAA6B;MAAM,OAAO,MAAM;MAAQ,OAAM;KAAU,GAA1D,QAA0D;KACxE,oBAAC,UAAD;MAA2B;MAAM,OAAO,MAAM;MAAM,OAAM;KAAQ,GAApD,MAAoD;KAClE,oBAAC,UAAD;MAA4B;MAAM,OAAO,MAAM;MAAO,OAAM;KAAS,GAAvD,OAAuD;IAChE;;EACJ,CAAA;CACE,CAAA;AAEb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScaleRow.mjs","names":["Flexbox"],"sources":["../../../src/color/CssVar/ScaleRow.tsx"],"sourcesContent":["import { message, Space } from 'antd';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { copyToClipboard } from '@/utils/copyToClipboard';\n\nimport { styles } from './style';\n\nexport interface IScaleRow {\n name: string;\n scale: string[];\n title: 'light' | 'dark';\n}\n\nconst ScaleRow = memo<IScaleRow>(({ name, title, scale }) => {\n const style = {};\n const isAlpha = false;\n\n return (\n <Space size={2}>\n <div className={styles.scaleRowTitle} key={title}>\n <div className={styles.text}>{title}</div>\n </div>\n {scale.map((color, index) => {\n if (index === 0 || index === 12) return false;\n\n return (\n <div\n className={styles.scaleBox}\n key={index}\n style={style}\n title={color}\n onClick={async () => {\n const content = `token.${name}${index}${isAlpha ? 'A' : ''} /* ${color} */`;\n\n await copyToClipboard(content);\n message.success(content);\n }}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{ backgroundColor: color }}\n />\n </div>\n );\n })}\n </Space>\n );\n});\n\nexport default ScaleRow;\n"],"mappings":";;;;;;;AAcA,MAAM,WAAW,MAAiB,EAAE,MAAM,OAAO,YAAY;CAC3D,MAAM,QAAQ,CAAC;CAGf,OACE,qBAAC,OAAD;EAAO,MAAM;
|
|
1
|
+
{"version":3,"file":"ScaleRow.mjs","names":["Flexbox"],"sources":["../../../src/color/CssVar/ScaleRow.tsx"],"sourcesContent":["import { message, Space } from 'antd';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { copyToClipboard } from '@/utils/copyToClipboard';\n\nimport { styles } from './style';\n\nexport interface IScaleRow {\n name: string;\n scale: string[];\n title: 'light' | 'dark';\n}\n\nconst ScaleRow = memo<IScaleRow>(({ name, title, scale }) => {\n const style = {};\n const isAlpha = false;\n\n return (\n <Space size={2}>\n <div className={styles.scaleRowTitle} key={title}>\n <div className={styles.text}>{title}</div>\n </div>\n {scale.map((color, index) => {\n if (index === 0 || index === 12) return false;\n\n return (\n <div\n className={styles.scaleBox}\n key={index}\n style={style}\n title={color}\n onClick={async () => {\n const content = `token.${name}${index}${isAlpha ? 'A' : ''} /* ${color} */`;\n\n await copyToClipboard(content);\n message.success(content);\n }}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{ backgroundColor: color }}\n />\n </div>\n );\n })}\n </Space>\n );\n});\n\nexport default ScaleRow;\n"],"mappings":";;;;;;;AAcA,MAAM,WAAW,MAAiB,EAAE,MAAM,OAAO,YAAY;CAC3D,MAAM,QAAQ,CAAC;CAGf,OACE,qBAAC,OAAD;EAAO,MAAM;EAAb,UAAA,CACE,oBAAC,OAAD;GAAK,WAAW,OAAO;GACrB,UAAA,oBAAC,OAAD;IAAK,WAAW,OAAO;IAAO,UAAA;GAAW,CAAA;EACtC,GAFsC,KAEtC,GACJ,MAAM,KAAK,OAAO,UAAU;GAC3B,IAAI,UAAU,KAAK,UAAU,IAAI,OAAO;GAExC,OACE,oBAAC,OAAD;IACE,WAAW,OAAO;IAEX;IACP,OAAO;IACP,SAAS,YAAY;KACnB,MAAM,UAAU,SAAS,OAAO,MAAA,MAAiC,MAAM;KAEvE,MAAM,gBAAgB,OAAO;KAC7B,QAAQ,QAAQ,OAAO;IACzB;IAEA,UAAA,oBAACA,mBAAD;KACE,YAAA;KACA,OAAO;KACP,WAAW,OAAO;KAClB,SAAS;KACT,OAAO,EAAE,iBAAiB,MAAM;IACjC,CAAA;GACE,GAjBE,KAiBF;EAET,CAAC,CACI;;AAEX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VarRow.mjs","names":["Flexbox"],"sources":["../../../src/color/CssVar/VarRow.tsx"],"sourcesContent":["import { message, Space } from 'antd';\nimport { cssVar } from 'antd-style';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { copyToClipboard } from '@/utils/copyToClipboard';\n\nimport { styles } from './style';\n\nexport interface IScaleRow {\n name: string;\n}\n\nconst ScaleRow = memo<IScaleRow>(({ name }) => {\n return (\n <Space size={2}>\n <div className={styles.scaleRowTitle} key={name}>\n <div className={styles.text}>cssVar</div>\n </div>\n {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((color) => {\n return (\n <div\n className={styles.scaleBox}\n key={color}\n title={(cssVar as any)[`${name}${color}`] as any}\n onClick={async () => {\n const content = (cssVar as any)[`${name}${color}`] as any;\n\n await copyToClipboard(content);\n message.success(content);\n }}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{ backgroundColor: (cssVar as any)[`${name}${color}`] as any }}\n />\n </div>\n );\n })}\n </Space>\n );\n});\n\nexport default ScaleRow;\n"],"mappings":";;;;;;;;AAaA,MAAM,WAAW,MAAiB,EAAE,WAAW;CAC7C,OACE,qBAAC,OAAD;EAAO,MAAM;
|
|
1
|
+
{"version":3,"file":"VarRow.mjs","names":["Flexbox"],"sources":["../../../src/color/CssVar/VarRow.tsx"],"sourcesContent":["import { message, Space } from 'antd';\nimport { cssVar } from 'antd-style';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { copyToClipboard } from '@/utils/copyToClipboard';\n\nimport { styles } from './style';\n\nexport interface IScaleRow {\n name: string;\n}\n\nconst ScaleRow = memo<IScaleRow>(({ name }) => {\n return (\n <Space size={2}>\n <div className={styles.scaleRowTitle} key={name}>\n <div className={styles.text}>cssVar</div>\n </div>\n {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((color) => {\n return (\n <div\n className={styles.scaleBox}\n key={color}\n title={(cssVar as any)[`${name}${color}`] as any}\n onClick={async () => {\n const content = (cssVar as any)[`${name}${color}`] as any;\n\n await copyToClipboard(content);\n message.success(content);\n }}\n >\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{ backgroundColor: (cssVar as any)[`${name}${color}`] as any }}\n />\n </div>\n );\n })}\n </Space>\n );\n});\n\nexport default ScaleRow;\n"],"mappings":";;;;;;;;AAaA,MAAM,WAAW,MAAiB,EAAE,WAAW;CAC7C,OACE,qBAAC,OAAD;EAAO,MAAM;EAAb,UAAA,CACE,oBAAC,OAAD;GAAK,WAAW,OAAO;GACrB,UAAA,oBAAC,OAAD;IAAK,WAAW,OAAO;IAAM,UAAA;GAAW,CAAA;EACrC,GAFsC,IAEtC,GACJ;GAAC;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;GAAG;EAAE,CAAC,CAAC,KAAK,UAAU;GAC9C,OACE,oBAAC,OAAD;IACE,WAAW,OAAO;IAElB,OAAQ,OAAe,GAAG,OAAO;IACjC,SAAS,YAAY;KACnB,MAAM,UAAW,OAAe,GAAG,OAAO;KAE1C,MAAM,gBAAgB,OAAO;KAC7B,QAAQ,QAAQ,OAAO;IACzB;IAEA,UAAA,oBAACA,mBAAD;KACE,YAAA;KACA,OAAO;KACP,WAAW,OAAO;KAClB,SAAS;KACT,OAAO,EAAE,iBAAkB,OAAe,GAAG,OAAO,SAAgB;IACrE,CAAA;GACE,GAhBE,KAgBF;EAET,CAAC,CACI;;AAEX,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["Flexbox","VarRow"],"sources":["../../../src/color/CssVar/index.tsx"],"sourcesContent":["'use client';\n\nimport { Space } from 'antd';\nimport { useThemeMode } from 'antd-style';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\n\nimport { type ColorScaleItem } from '../types';\nimport ScaleRow from './ScaleRow';\nimport { styles } from './style';\nimport VarRow from './VarRow';\n\nexport interface ColorScalesProps {\n /**\n * @description Index of the mid highlight color in the scale\n */\n midHighLight: number;\n /**\n * @description Name of the color scale\n */\n name: string;\n /**\n * @description Color scale item object\n */\n scale: ColorScaleItem;\n}\n\nconst ColorScales = memo<ColorScalesProps>(({ name, scale, midHighLight }) => {\n const { isDarkMode } = useThemeMode();\n return (\n <Flexbox horizontal align={'center'} flex={1} justify={'center'}>\n <div style={{ padding: '8px 16px 32px 0' }}>\n <Space direction={'vertical'} size={2}>\n <Space key=\"scale-title\" size={2}>\n <Flexbox horizontal align={'center'} className={styles.scaleRowTitle} key=\"scale-num\" />\n {Array.from({ length: scale.light.length })\n .fill('')\n .map((_, index) => {\n if (index === 0 || index === 12) return false;\n\n const isMidHighlight = midHighLight === index;\n\n return (\n <div className={styles.scaleBox} key={`num${index}`}>\n <div className={styles.scaleBox}>\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{\n fontWeight: isMidHighlight ? 700 : 400,\n opacity: 0.5,\n }}\n >\n {index}\n </Flexbox>\n </div>\n </div>\n );\n })}\n </Space>\n <VarRow name={name} />\n {isDarkMode ? (\n <>\n <ScaleRow key=\"dark\" name={name} scale={scale.dark} title=\"dark\" />\n <ScaleRow key=\"light\" name={name} scale={scale.light} title=\"light\" />\n </>\n ) : (\n <>\n {' '}\n <ScaleRow key=\"light\" name={name} scale={scale.light} title=\"light\" />\n <ScaleRow key=\"dark\" name={name} scale={scale.dark} title=\"dark\" />\n </>\n )}\n </Space>\n </div>\n </Flexbox>\n );\n});\n\nexport default ColorScales;\n"],"mappings":";;;;;;;;;;AA4BA,MAAM,cAAc,MAAwB,EAAE,MAAM,OAAO,mBAAmB;CAC5E,MAAM,EAAE,eAAe,aAAa;CACpC,OACE,oBAACA,mBAAD;EAAS,YAAA;EAAW,OAAO;EAAU,MAAM;EAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["Flexbox","VarRow"],"sources":["../../../src/color/CssVar/index.tsx"],"sourcesContent":["'use client';\n\nimport { Space } from 'antd';\nimport { useThemeMode } from 'antd-style';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\n\nimport { type ColorScaleItem } from '../types';\nimport ScaleRow from './ScaleRow';\nimport { styles } from './style';\nimport VarRow from './VarRow';\n\nexport interface ColorScalesProps {\n /**\n * @description Index of the mid highlight color in the scale\n */\n midHighLight: number;\n /**\n * @description Name of the color scale\n */\n name: string;\n /**\n * @description Color scale item object\n */\n scale: ColorScaleItem;\n}\n\nconst ColorScales = memo<ColorScalesProps>(({ name, scale, midHighLight }) => {\n const { isDarkMode } = useThemeMode();\n return (\n <Flexbox horizontal align={'center'} flex={1} justify={'center'}>\n <div style={{ padding: '8px 16px 32px 0' }}>\n <Space direction={'vertical'} size={2}>\n <Space key=\"scale-title\" size={2}>\n <Flexbox horizontal align={'center'} className={styles.scaleRowTitle} key=\"scale-num\" />\n {Array.from({ length: scale.light.length })\n .fill('')\n .map((_, index) => {\n if (index === 0 || index === 12) return false;\n\n const isMidHighlight = midHighLight === index;\n\n return (\n <div className={styles.scaleBox} key={`num${index}`}>\n <div className={styles.scaleBox}>\n <Flexbox\n horizontal\n align={'center'}\n className={styles.scaleItem}\n justify={'center'}\n style={{\n fontWeight: isMidHighlight ? 700 : 400,\n opacity: 0.5,\n }}\n >\n {index}\n </Flexbox>\n </div>\n </div>\n );\n })}\n </Space>\n <VarRow name={name} />\n {isDarkMode ? (\n <>\n <ScaleRow key=\"dark\" name={name} scale={scale.dark} title=\"dark\" />\n <ScaleRow key=\"light\" name={name} scale={scale.light} title=\"light\" />\n </>\n ) : (\n <>\n {' '}\n <ScaleRow key=\"light\" name={name} scale={scale.light} title=\"light\" />\n <ScaleRow key=\"dark\" name={name} scale={scale.dark} title=\"dark\" />\n </>\n )}\n </Space>\n </div>\n </Flexbox>\n );\n});\n\nexport default ColorScales;\n"],"mappings":";;;;;;;;;;AA4BA,MAAM,cAAc,MAAwB,EAAE,MAAM,OAAO,mBAAmB;CAC5E,MAAM,EAAE,eAAe,aAAa;CACpC,OACE,oBAACA,mBAAD;EAAS,YAAA;EAAW,OAAO;EAAU,MAAM;EAAG,SAAS;EACrD,UAAA,oBAAC,OAAD;GAAK,OAAO,EAAE,SAAS,kBAAkB;GACvC,UAAA,qBAAC,OAAD;IAAO,WAAW;IAAY,MAAM;IAApC,UAAA;KACE,qBAAC,OAAD;MAAyB,MAAM;MAA/B,UAAA,CACE,oBAACA,mBAAD;OAAS,YAAA;OAAW,OAAO;OAAU,WAAW,OAAO;MAAgC,GAAb,WAAa,GACtF,MAAM,KAAK,EAAE,QAAQ,MAAM,MAAM,OAAO,CAAC,CAAC,CACxC,KAAK,EAAE,CAAC,CACR,KAAK,GAAG,UAAU;OACjB,IAAI,UAAU,KAAK,UAAU,IAAI,OAAO;OAExC,MAAM,iBAAiB,iBAAiB;OAExC,OACE,oBAAC,OAAD;QAAK,WAAW,OAAO;QACrB,UAAA,oBAAC,OAAD;SAAK,WAAW,OAAO;SACrB,UAAA,oBAACA,mBAAD;UACE,YAAA;UACA,OAAO;UACP,WAAW,OAAO;UAClB,SAAS;UACT,OAAO;WACL,YAAY,iBAAiB,MAAM;WACnC,SAAS;UACX;UAEC,UAAA;SACM,CAAA;QACN,CAAA;OACF,GAfiC,MAAM,OAevC;MAET,CAAC,CACE;KA5BI,GAAA,aA4BJ;KACP,oBAACC,YAAD,EAAc,KAAO,CAAA;KACpB,aACC,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,UAAD;MAA2B;MAAM,OAAO,MAAM;MAAM,OAAM;KAAQ,GAApD,MAAoD,GAClE,oBAAC,UAAD;MAA4B;MAAM,OAAO,MAAM;MAAO,OAAM;KAAS,GAAvD,OAAuD,CACrE,EAAA,CAAA,IAEF,qBAAA,YAAA,EAAA,UAAA;MACG;MACD,oBAAC,UAAD;OAA4B;OAAM,OAAO,MAAM;OAAO,OAAM;MAAS,GAAvD,OAAuD;MACrE,oBAAC,UAAD;OAA2B;OAAM,OAAO,MAAM;OAAM,OAAM;MAAQ,GAApD,MAAoD;KAClE,EAAA,CAAA;IAEC;;EACJ,CAAA;CACE,CAAA;AAEb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"latex.mjs","names":[],"sources":["../../../src/hooks/useMarkdown/latex.ts"],"sourcesContent":["import { renderToString } from 'katex';\n\n// ============================================================================\n// Utility Classes\n// ============================================================================\n\n/**\n * PlaceholderManager - Manages temporary replacement and restoration of protected content\n * Used to protect code blocks and LaTeX expressions during preprocessing\n */\nclass PlaceholderManager {\n private placeholders: string[] = [];\n private prefix: string;\n\n constructor(prefix = 'PROTECTED') {\n this.prefix = prefix;\n }\n\n add(content: string): string {\n const index = this.placeholders.length;\n this.placeholders.push(content);\n return `<<${this.prefix}_${index}>>`;\n }\n\n restore(text: string): string {\n return text.replaceAll(new RegExp(`<<${this.prefix}_(\\\\d+)>>`, 'g'), (_, index) => {\n return this.placeholders[Number.parseInt(index)] || '';\n });\n }\n\n clear(): void {\n this.placeholders = [];\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n// Helper: replace unescaped pipes with \\vert within a LaTeX math fragment\nconst replaceUnescapedPipes = (formula: string): string =>\n // Use \\vert{} so the control sequence terminates before the next token\n formula.replaceAll(/(?<!\\\\)\\|/g, '\\\\vert{}');\n\n/**\n * Converts LaTeX bracket delimiters to dollar sign delimiters.\n * Converts \\[...\\] to $$...$$ and \\(...\\) to $...$\n * Preserves code blocks during the conversion.\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with LaTeX bracket delimiters converted to dollar sign delimiters\n */\nexport function convertLatexDelimiters(text: string): string {\n const pattern = /(```[\\s\\S]*?```|`.*?`)|\\\\\\[([\\s\\S]*?[^\\\\])\\\\\\]|\\\\\\((.*?)\\\\\\)/g;\n return text.replaceAll(\n pattern,\n (\n match: string,\n codeBlock: string | undefined,\n squareBracket: string | undefined,\n roundBracket: string | undefined,\n ): string => {\n if (codeBlock !== undefined) {\n return codeBlock;\n } else if (squareBracket !== undefined) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket !== undefined) {\n return `$${roundBracket}$`;\n }\n return match;\n },\n );\n}\n\n/**\n * Escapes mhchem commands in LaTeX expressions to ensure proper rendering.\n *\n * @param text The input string containing LaTeX expressions with mhchem commands\n * @returns The string with escaped mhchem commands\n */\nexport function escapeMhchemCommands(text: string) {\n return text.replaceAll('$\\\\ce{', '$\\\\\\\\ce{').replaceAll('$\\\\pu{', '$\\\\\\\\pu{');\n}\n\n/**\n * Escapes pipe characters within LaTeX expressions to prevent them from being interpreted\n * as table column separators in markdown tables.\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with pipe characters escaped in LaTeX expressions\n */\nexport function escapeLatexPipes(text: string): string {\n // Replace unescaped '|' inside LaTeX math spans with '\\vert' so that\n // remark-gfm table parsing won't treat them as column separators.\n // Leave code blocks/inline code untouched.\n // Also ignore escaped dollars (\\$) which are currency symbols\n\n // Process code blocks first to protect them\n const codeBlocks: string[] = [];\n let content = text.replaceAll(/(```[\\s\\S]*?```|`[^\\n`]*`)/g, (match) => {\n codeBlocks.push(match);\n return `<<CODE_${codeBlocks.length - 1}>>`;\n });\n\n // For display math, allow multiline\n content = content.replaceAll(/\\$\\$([\\s\\S]*?)\\$\\$/g, (match, display) => {\n return `$$${replaceUnescapedPipes(display)}$$`;\n });\n\n // For inline math, use non-greedy match that DOES NOT cross newlines\n // This prevents issues in tables where $ might appear in different cells\n content = content.replaceAll(/(?<!\\\\)\\$(?!\\$)([^\\n$]*)(?<!\\\\)\\$(?!\\$)/g, (match, inline) => {\n return `$${replaceUnescapedPipes(inline)}$`;\n });\n\n // Restore code blocks\n content = content.replaceAll(/<<CODE_(\\d+)>>/g, (_, index) => {\n return codeBlocks[Number.parseInt(index)];\n });\n\n return content;\n}\n\n/**\n * Escapes underscores within \\text{...} commands in LaTeX expressions\n * that are not already escaped.\n * For example, \\text{node_domain} becomes \\text{node\\_domain},\n * but \\text{node\\_domain} remains \\text{node\\_domain}.\n *\n * @param text The input string potentially containing LaTeX expressions\n * @returns The string with unescaped underscores escaped within \\text{...} commands\n */\nexport function escapeTextUnderscores(text: string): string {\n return text.replaceAll(/\\\\text\\{([^}]*)\\}/g, (match, textContent: string) => {\n // textContent is the content within the braces, e.g., \"node_domain\" or \"already\\_escaped\"\n // Replace underscores '_' with '\\_' only if they are NOT preceded by a backslash '\\'.\n // The (?<!\\\\) is a negative lookbehind assertion that ensures the character before '_' is not a '\\'.\n const escapedTextContent = textContent.replaceAll(/(?<!\\\\)_/g, '\\\\_');\n return `\\\\text{${escapedTextContent}}`;\n });\n}\n\n/**\n * Escapes dollar signs that appear to be currency symbols to prevent them from being\n * interpreted as LaTeX math delimiters.\n *\n * This function identifies currency patterns such as:\n * - $20, $100, $1,000\n * - $20-50, $100+\n * - Patterns within markdown tables\n *\n * @param text The input string containing potential currency symbols\n * @returns The string with currency dollar signs escaped\n */\nexport function escapeCurrencyDollars(text: string): string {\n // Protect code blocks and existing LaTeX expressions from processing\n const manager = new PlaceholderManager('PROTECTED');\n\n let content = text.replaceAll(\n // Match patterns to protect (in order):\n // 1. Code blocks: ```...```\n // 2. Inline code: `...`\n // 3. Display math: $$...$$\n // 4. Inline math with LaTeX commands: $...\\...$ (must contain backslash to distinguish from currency)\n // 5. Simple number formulas: $1$, $10$, $100$ (pure digits in math mode)\n // 6. Number lists in math mode: $1,-1,0$ or $1,2,3$ (comma-separated numbers, possibly negative)\n // 7. LaTeX bracket notation: \\[...\\]\n // 8. LaTeX parenthesis notation: \\(...\\)\n /(```[\\s\\S]*?```|`[^\\n`]*`|\\$\\$[\\s\\S]*?\\$\\$|(?<!\\\\)\\$(?!\\$)(?=[\\s\\S]*?\\\\)[\\s\\S]*?(?<!\\\\)\\$(?!\\$)|\\$\\d+\\$|\\$-?\\d+(?:,-?\\d+)+\\$|\\\\\\[[\\s\\S]*?\\\\\\]|\\\\\\(.*?\\\\\\))/g,\n (match) => manager.add(match),\n );\n\n // Escape dollar signs that are clearly currency:\n // - $ followed by a digit\n // - Not preceded by another $ (to avoid breaking $$)\n // - Not followed immediately by another $ (to avoid breaking $1$ LaTeX)\n // - Followed by number patterns with optional commas, decimals, ranges, or plus signs\n // Match patterns like: $20, $1,000, $19.99, $20-50, $300+, $1,000-2,000+\n // But NOT: $1$, $2$ (these are LaTeX formulas)\n // In the replacement: \\\\ = backslash, $$ = literal $, $1 = capture group 1\n content = content.replaceAll(\n /(?<!\\$)\\$(\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?(?:-\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?)?\\+?)(?!\\$)/g,\n '\\\\$$$1',\n );\n\n // Restore protected content\n content = manager.restore(content);\n\n return content;\n}\n\n// Old simple preprocessLaTeX has been replaced by the comprehensive version below\n// The new preprocessLaTeX provides the same default behavior with optional advanced featuresgit\n\n/**\n * Extracts the LaTeX formula after the last $$ delimiter if there's an odd number of $$ delimiters.\n *\n * @param text The input string containing LaTeX formulas\n * @returns The content after the last $$ if there's an odd number of $$, otherwise an empty string\n */\nconst extractIncompleteFormula = (text: string) => {\n // Count the number of $$ delimiters\n const dollarsCount = (text.match(/\\$\\$/g) || []).length;\n\n // If odd number of $$ delimiters, extract content after the last $$\n if (dollarsCount % 2 === 1) {\n const match = text.match(/\\$\\$([\\s\\S]*)$/);\n return match ? match[1] : '';\n }\n\n // If even number of $$ delimiters, return empty string\n return '';\n};\n\n/**\n * Checks if the last LaTeX formula in the text is renderable.\n * Only validates the formula after the last $$ if there's an odd number of $$.\n *\n * @param text The input string containing LaTeX formulas\n * @returns True if the last formula is renderable or if there's no incomplete formula\n */\nexport const isLastFormulaRenderable = (text: string) => {\n const formula = extractIncompleteFormula(text);\n\n // If no incomplete formula, return true\n if (!formula) return true;\n\n // Try to render the last formula\n try {\n renderToString(formula, {\n displayMode: true,\n throwOnError: true,\n });\n return true;\n } catch (error) {\n console.error(`LaTeX formula rendering error: ${error}`);\n return false;\n }\n};\n\n// ============================================================================\n// Advanced Preprocessing Functions\n// ============================================================================\n\n/**\n * Fixes common LaTeX syntax errors automatically\n * - Balances unmatched braces\n * - Balances \\left and \\right delimiters\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with fixed LaTeX expressions\n */\nexport function fixCommonLaTeXErrors(text: string): string {\n return text.replaceAll(/(\\$\\$[\\s\\S]*?\\$\\$|\\$[\\s\\S]*?\\$)/g, (match) => {\n let fixed = match;\n\n // Fix unbalanced braces\n const openBraces = (fixed.match(/(?<!\\\\)\\{/g) || []).length;\n const closeBraces = (fixed.match(/(?<!\\\\)\\}/g) || []).length;\n if (openBraces > closeBraces) {\n const diff = openBraces - closeBraces;\n const closingBraces = '}'.repeat(diff);\n // Insert before the closing delimiter\n fixed = fixed.replace(/(\\$\\$?)$/, closingBraces + '$1');\n }\n\n // Fix unbalanced \\left and \\right\n const leftDelims = (fixed.match(/\\\\left[(.<[{|]/g) || []).length;\n const rightDelims = (fixed.match(/\\\\right[).>\\]|}]/g) || []).length;\n if (leftDelims > rightDelims) {\n const diff = leftDelims - rightDelims;\n const rightDots = '\\\\right.'.repeat(diff);\n fixed = fixed.replace(/(\\$\\$?)$/, rightDots + '$1');\n }\n\n return fixed;\n });\n}\n\n/**\n * Normalizes whitespace in LaTeX expressions\n * - Removes extra spaces around $ delimiters\n * - Normalizes multiple spaces to single space inside formulas\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with normalized whitespace\n */\nexport function normalizeLatexSpacing(text: string): string {\n let result = text;\n\n // Remove spaces inside $ delimiters (at the edges)\n result = result.replaceAll(/\\$\\s+/g, '$');\n result = result.replaceAll(/\\s+\\$/g, '$');\n result = result.replaceAll(/\\$\\$\\s+/g, '$$');\n result = result.replaceAll(/\\s+\\$\\$/g, '$$');\n\n // Normalize multiple spaces inside formulas to single space\n result = result.replaceAll(/(\\$\\$[\\s\\S]*?\\$\\$|\\$[\\s\\S]*?\\$)/g, (match) => {\n return match.replaceAll(/\\s{2,}/g, ' ');\n });\n\n return result;\n}\n\n/**\n * Validates all LaTeX expressions in the text\n * Returns detailed information about validation results\n *\n * @param text The input string containing LaTeX expressions\n * @returns Validation results with errors if any\n */\nexport function validateLatexExpressions(text: string): {\n errors: Array<{\n formula: string;\n message: string;\n position: number;\n type: 'display' | 'inline';\n }>;\n totalExpressions: number;\n valid: boolean;\n} {\n const errors: Array<{\n formula: string;\n message: string;\n position: number;\n type: 'display' | 'inline';\n }> = [];\n\n let totalExpressions = 0;\n const pattern = /\\$\\$([\\s\\S]*?)\\$\\$|(?<!\\\\)\\$(?!\\$)([\\s\\S]*?)(?<!\\\\)\\$(?!\\$)/g;\n let match;\n\n while ((match = pattern.exec(text)) !== null) {\n totalExpressions++;\n const formula = match[1] || match[2];\n const isDisplay = match[0].startsWith('$$');\n\n try {\n renderToString(formula, {\n displayMode: isDisplay,\n strict: 'warn',\n throwOnError: true,\n trust: false,\n });\n } catch (error) {\n errors.push({\n formula: formula.slice(0, 50) + (formula.length > 50 ? '...' : ''),\n message: error instanceof Error ? error.message : String(error),\n position: match.index,\n type: isDisplay ? 'display' : 'inline',\n });\n }\n }\n\n return {\n errors,\n totalExpressions,\n valid: errors.length === 0,\n };\n}\n\n/**\n * Handles CJK (Chinese, Japanese, Korean) characters mixed with LaTeX\n * Optionally adds spaces between CJK characters and LaTeX expressions for better rendering\n *\n * @param text The input string\n * @param addSpaces Whether to add spaces between CJK and LaTeX (default: false)\n * @returns The processed string\n */\nexport function handleCJKWithLatex(text: string, addSpaces = false): string {\n if (!addSpaces) return text;\n\n let result = text;\n\n // Add space between CJK character and opening $\n result = result.replaceAll(/([\\u3040-\\u30FF\\u4E00-\\u9FA5])(\\$)/g, '$1 $2');\n\n // Add space between closing $ and CJK character\n result = result.replaceAll(/(\\$)([\\u3040-\\u30FF\\u4E00-\\u9FA5])/g, '$1 $2');\n\n return result;\n}\n\n// ============================================================================\n// Advanced Preprocessing Options\n// ============================================================================\n\nexport interface AdvancedPreprocessOptions {\n /** Add spaces between CJK and LaTeX (default: false, requires handleCJK: true) */\n addCJKSpaces?: boolean;\n /** Convert bracket notation \\[...\\] to $$...$$ (default: true) */\n convertBrackets?: boolean;\n /** Enable currency escaping (default: true) */\n escapeCurrency?: boolean;\n /** Escape mhchem commands (default: true) */\n escapeMhchem?: boolean;\n /** Escape pipe symbols in LaTeX (default: true) */\n escapePipes?: boolean;\n /** Escape underscores in \\text{} (default: true) */\n escapeUnderscores?: boolean;\n /** Automatically fix common LaTeX errors (default: false) */\n fixErrors?: boolean;\n /** Handle CJK characters (default: false) */\n handleCJK?: boolean;\n /** Normalize whitespace (default: false) */\n normalizeSpacing?: boolean;\n /** Throw error on validation failure (default: false, requires validate: true) */\n throwOnValidationError?: boolean;\n /** Validate LaTeX syntax (default: false) */\n validate?: boolean;\n}\n\n/**\n * Comprehensive LaTeX preprocessing with configurable options\n *\n * This is the main preprocessing function that handles:\n * - Currency symbol escaping (e.g., $20 → \\$20)\n * - LaTeX delimiter conversion (\\[...\\] → $$...$$)\n * - Special character escaping (pipes, underscores, mhchem)\n * - Optional error fixing and validation\n * - Optional CJK character handling\n *\n * @param text The input string containing LaTeX and Markdown\n * @param options Configuration options for fine-grained control\n * @returns The preprocessed string\n *\n * @example\n * ```ts\n * // Default behavior (same as old preprocessLaTeX)\n * preprocessLaTeX('向量$90^\\\\circ$,非 $0^\\\\circ$ 和 $180^\\\\circ$')\n *\n * // With custom options\n * preprocessLaTeX(text, {\n * fixErrors: true,\n * validate: true,\n * handleCJK: true\n * })\n * ```\n */\nexport function preprocessLaTeX(text: string, options: AdvancedPreprocessOptions = {}): string {\n const {\n addCJKSpaces = false,\n convertBrackets = true,\n escapeCurrency = true,\n escapeMhchem = true,\n escapePipes = true,\n escapeUnderscores = true,\n fixErrors = false,\n handleCJK = false,\n normalizeSpacing = false,\n throwOnValidationError = false,\n validate = false,\n } = options;\n\n let content = text;\n\n // Phase 1: Currency escaping (if enabled)\n if (escapeCurrency) {\n content = escapeCurrencyDollars(content);\n }\n\n // Phase 2: Bracket conversion (if enabled)\n if (convertBrackets) {\n content = convertLatexDelimiters(content);\n }\n\n // Phase 3: LaTeX-specific escaping\n if (escapeMhchem) {\n content = escapeMhchemCommands(content);\n }\n\n if (escapePipes) {\n content = escapeLatexPipes(content);\n }\n\n if (escapeUnderscores) {\n content = escapeTextUnderscores(content);\n }\n\n // Phase 4: Error fixing (if enabled)\n if (fixErrors) {\n content = fixCommonLaTeXErrors(content);\n }\n\n // Phase 5: Whitespace normalization (if enabled)\n if (normalizeSpacing) {\n content = normalizeLatexSpacing(content);\n }\n\n // Phase 6: CJK handling (if enabled)\n if (handleCJK) {\n content = handleCJKWithLatex(content, addCJKSpaces);\n }\n\n // Phase 7: Validation (if enabled)\n if (validate) {\n const validation = validateLatexExpressions(content);\n if (!validation.valid) {\n const errorMessage = `LaTeX validation failed (${validation.errors.length}/${validation.totalExpressions} expressions have errors):\\n${validation.errors.map((e) => ` - [${e.type}] at position ${e.position}: ${e.message}\\n Formula: ${e.formula}`).join('\\n')}`;\n\n if (throwOnValidationError) {\n throw new Error(errorMessage);\n } else {\n console.warn(errorMessage);\n }\n }\n }\n\n return content;\n}\n\n/**\n * Strict preprocessing mode - enables all safety features and validations\n * Use this when you want maximum correctness and are willing to accept the performance cost\n *\n * @param text The input string\n * @returns The preprocessed string with all features enabled\n *\n * @example\n * ```ts\n * const processed = preprocessLaTeXStrict(userInput)\n * // Enables: error fixing, validation, CJK handling, space normalization\n * ```\n */\nexport function preprocessLaTeXStrict(text: string): string {\n return preprocessLaTeX(text, {\n addCJKSpaces: false, // Usually don't want extra spaces\n convertBrackets: true,\n escapeCurrency: true,\n escapeMhchem: true,\n escapePipes: true,\n escapeUnderscores: true,\n fixErrors: true,\n handleCJK: true,\n normalizeSpacing: true,\n throwOnValidationError: false, // Warn but don't throw\n validate: true,\n });\n}\n\n/**\n * Minimal preprocessing mode - only essential operations\n * Use this for better performance when you control the input\n *\n * @param text The input string\n * @returns The preprocessed string with minimal processing\n *\n * @example\n * ```ts\n * const processed = preprocessLaTeXMinimal(trustedInput)\n * // Only escapes currency and converts brackets\n * ```\n */\nexport function preprocessLaTeXMinimal(text: string): string {\n return preprocessLaTeX(text, {\n convertBrackets: true,\n escapeCurrency: true,\n escapeMhchem: false,\n escapePipes: false,\n escapeUnderscores: false,\n fixErrors: false,\n handleCJK: false,\n normalizeSpacing: false,\n validate: false,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"latex.mjs","names":[],"sources":["../../../src/hooks/useMarkdown/latex.ts"],"sourcesContent":["import { renderToString } from 'katex';\n\n// ============================================================================\n// Utility Classes\n// ============================================================================\n\n/**\n * PlaceholderManager - Manages temporary replacement and restoration of protected content\n * Used to protect code blocks and LaTeX expressions during preprocessing\n */\nclass PlaceholderManager {\n private placeholders: string[] = [];\n private prefix: string;\n\n constructor(prefix = 'PROTECTED') {\n this.prefix = prefix;\n }\n\n add(content: string): string {\n const index = this.placeholders.length;\n this.placeholders.push(content);\n return `<<${this.prefix}_${index}>>`;\n }\n\n restore(text: string): string {\n return text.replaceAll(new RegExp(`<<${this.prefix}_(\\\\d+)>>`, 'g'), (_, index) => {\n return this.placeholders[Number.parseInt(index)] || '';\n });\n }\n\n clear(): void {\n this.placeholders = [];\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n// Helper: replace unescaped pipes with \\vert within a LaTeX math fragment\nconst replaceUnescapedPipes = (formula: string): string =>\n // Use \\vert{} so the control sequence terminates before the next token\n formula.replaceAll(/(?<!\\\\)\\|/g, '\\\\vert{}');\n\n/**\n * Converts LaTeX bracket delimiters to dollar sign delimiters.\n * Converts \\[...\\] to $$...$$ and \\(...\\) to $...$\n * Preserves code blocks during the conversion.\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with LaTeX bracket delimiters converted to dollar sign delimiters\n */\nexport function convertLatexDelimiters(text: string): string {\n const pattern = /(```[\\s\\S]*?```|`.*?`)|\\\\\\[([\\s\\S]*?[^\\\\])\\\\\\]|\\\\\\((.*?)\\\\\\)/g;\n return text.replaceAll(\n pattern,\n (\n match: string,\n codeBlock: string | undefined,\n squareBracket: string | undefined,\n roundBracket: string | undefined,\n ): string => {\n if (codeBlock !== undefined) {\n return codeBlock;\n } else if (squareBracket !== undefined) {\n return `$$${squareBracket}$$`;\n } else if (roundBracket !== undefined) {\n return `$${roundBracket}$`;\n }\n return match;\n },\n );\n}\n\n/**\n * Escapes mhchem commands in LaTeX expressions to ensure proper rendering.\n *\n * @param text The input string containing LaTeX expressions with mhchem commands\n * @returns The string with escaped mhchem commands\n */\nexport function escapeMhchemCommands(text: string) {\n return text.replaceAll('$\\\\ce{', '$\\\\\\\\ce{').replaceAll('$\\\\pu{', '$\\\\\\\\pu{');\n}\n\n/**\n * Escapes pipe characters within LaTeX expressions to prevent them from being interpreted\n * as table column separators in markdown tables.\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with pipe characters escaped in LaTeX expressions\n */\nexport function escapeLatexPipes(text: string): string {\n // Replace unescaped '|' inside LaTeX math spans with '\\vert' so that\n // remark-gfm table parsing won't treat them as column separators.\n // Leave code blocks/inline code untouched.\n // Also ignore escaped dollars (\\$) which are currency symbols\n\n // Process code blocks first to protect them\n const codeBlocks: string[] = [];\n let content = text.replaceAll(/(```[\\s\\S]*?```|`[^\\n`]*`)/g, (match) => {\n codeBlocks.push(match);\n return `<<CODE_${codeBlocks.length - 1}>>`;\n });\n\n // For display math, allow multiline\n content = content.replaceAll(/\\$\\$([\\s\\S]*?)\\$\\$/g, (match, display) => {\n return `$$${replaceUnescapedPipes(display)}$$`;\n });\n\n // For inline math, use non-greedy match that DOES NOT cross newlines\n // This prevents issues in tables where $ might appear in different cells\n content = content.replaceAll(/(?<!\\\\)\\$(?!\\$)([^\\n$]*)(?<!\\\\)\\$(?!\\$)/g, (match, inline) => {\n return `$${replaceUnescapedPipes(inline)}$`;\n });\n\n // Restore code blocks\n content = content.replaceAll(/<<CODE_(\\d+)>>/g, (_, index) => {\n return codeBlocks[Number.parseInt(index)];\n });\n\n return content;\n}\n\n/**\n * Escapes underscores within \\text{...} commands in LaTeX expressions\n * that are not already escaped.\n * For example, \\text{node_domain} becomes \\text{node\\_domain},\n * but \\text{node\\_domain} remains \\text{node\\_domain}.\n *\n * @param text The input string potentially containing LaTeX expressions\n * @returns The string with unescaped underscores escaped within \\text{...} commands\n */\nexport function escapeTextUnderscores(text: string): string {\n return text.replaceAll(/\\\\text\\{([^}]*)\\}/g, (match, textContent: string) => {\n // textContent is the content within the braces, e.g., \"node_domain\" or \"already\\_escaped\"\n // Replace underscores '_' with '\\_' only if they are NOT preceded by a backslash '\\'.\n // The (?<!\\\\) is a negative lookbehind assertion that ensures the character before '_' is not a '\\'.\n const escapedTextContent = textContent.replaceAll(/(?<!\\\\)_/g, '\\\\_');\n return `\\\\text{${escapedTextContent}}`;\n });\n}\n\n/**\n * Escapes dollar signs that appear to be currency symbols to prevent them from being\n * interpreted as LaTeX math delimiters.\n *\n * This function identifies currency patterns such as:\n * - $20, $100, $1,000\n * - $20-50, $100+\n * - Patterns within markdown tables\n *\n * @param text The input string containing potential currency symbols\n * @returns The string with currency dollar signs escaped\n */\nexport function escapeCurrencyDollars(text: string): string {\n // Protect code blocks and existing LaTeX expressions from processing\n const manager = new PlaceholderManager('PROTECTED');\n\n let content = text.replaceAll(\n // Match patterns to protect (in order):\n // 1. Code blocks: ```...```\n // 2. Inline code: `...`\n // 3. Display math: $$...$$\n // 4. Inline math with LaTeX commands: $...\\...$ (must contain backslash to distinguish from currency)\n // 5. Simple number formulas: $1$, $10$, $100$ (pure digits in math mode)\n // 6. Number lists in math mode: $1,-1,0$ or $1,2,3$ (comma-separated numbers, possibly negative)\n // 7. LaTeX bracket notation: \\[...\\]\n // 8. LaTeX parenthesis notation: \\(...\\)\n /(```[\\s\\S]*?```|`[^\\n`]*`|\\$\\$[\\s\\S]*?\\$\\$|(?<!\\\\)\\$(?!\\$)(?=[\\s\\S]*?\\\\)[\\s\\S]*?(?<!\\\\)\\$(?!\\$)|\\$\\d+\\$|\\$-?\\d+(?:,-?\\d+)+\\$|\\\\\\[[\\s\\S]*?\\\\\\]|\\\\\\(.*?\\\\\\))/g,\n (match) => manager.add(match),\n );\n\n // Escape dollar signs that are clearly currency:\n // - $ followed by a digit\n // - Not preceded by another $ (to avoid breaking $$)\n // - Not followed immediately by another $ (to avoid breaking $1$ LaTeX)\n // - Followed by number patterns with optional commas, decimals, ranges, or plus signs\n // Match patterns like: $20, $1,000, $19.99, $20-50, $300+, $1,000-2,000+\n // But NOT: $1$, $2$ (these are LaTeX formulas)\n // In the replacement: \\\\ = backslash, $$ = literal $, $1 = capture group 1\n content = content.replaceAll(\n /(?<!\\$)\\$(\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?(?:-\\d{1,3}(?:,\\d{3})*(?:\\.\\d+)?)?\\+?)(?!\\$)/g,\n '\\\\$$$1',\n );\n\n // Restore protected content\n content = manager.restore(content);\n\n return content;\n}\n\n// Old simple preprocessLaTeX has been replaced by the comprehensive version below\n// The new preprocessLaTeX provides the same default behavior with optional advanced featuresgit\n\n/**\n * Extracts the LaTeX formula after the last $$ delimiter if there's an odd number of $$ delimiters.\n *\n * @param text The input string containing LaTeX formulas\n * @returns The content after the last $$ if there's an odd number of $$, otherwise an empty string\n */\nconst extractIncompleteFormula = (text: string) => {\n // Count the number of $$ delimiters\n const dollarsCount = (text.match(/\\$\\$/g) || []).length;\n\n // If odd number of $$ delimiters, extract content after the last $$\n if (dollarsCount % 2 === 1) {\n const match = text.match(/\\$\\$([\\s\\S]*)$/);\n return match ? match[1] : '';\n }\n\n // If even number of $$ delimiters, return empty string\n return '';\n};\n\n/**\n * Checks if the last LaTeX formula in the text is renderable.\n * Only validates the formula after the last $$ if there's an odd number of $$.\n *\n * @param text The input string containing LaTeX formulas\n * @returns True if the last formula is renderable or if there's no incomplete formula\n */\nexport const isLastFormulaRenderable = (text: string) => {\n const formula = extractIncompleteFormula(text);\n\n // If no incomplete formula, return true\n if (!formula) return true;\n\n // Try to render the last formula\n try {\n renderToString(formula, {\n displayMode: true,\n throwOnError: true,\n });\n return true;\n } catch (error) {\n console.error(`LaTeX formula rendering error: ${error}`);\n return false;\n }\n};\n\n// ============================================================================\n// Advanced Preprocessing Functions\n// ============================================================================\n\n/**\n * Fixes common LaTeX syntax errors automatically\n * - Balances unmatched braces\n * - Balances \\left and \\right delimiters\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with fixed LaTeX expressions\n */\nexport function fixCommonLaTeXErrors(text: string): string {\n return text.replaceAll(/(\\$\\$[\\s\\S]*?\\$\\$|\\$[\\s\\S]*?\\$)/g, (match) => {\n let fixed = match;\n\n // Fix unbalanced braces\n const openBraces = (fixed.match(/(?<!\\\\)\\{/g) || []).length;\n const closeBraces = (fixed.match(/(?<!\\\\)\\}/g) || []).length;\n if (openBraces > closeBraces) {\n const diff = openBraces - closeBraces;\n const closingBraces = '}'.repeat(diff);\n // Insert before the closing delimiter\n fixed = fixed.replace(/(\\$\\$?)$/, closingBraces + '$1');\n }\n\n // Fix unbalanced \\left and \\right\n const leftDelims = (fixed.match(/\\\\left[(.<[{|]/g) || []).length;\n const rightDelims = (fixed.match(/\\\\right[).>\\]|}]/g) || []).length;\n if (leftDelims > rightDelims) {\n const diff = leftDelims - rightDelims;\n const rightDots = '\\\\right.'.repeat(diff);\n fixed = fixed.replace(/(\\$\\$?)$/, rightDots + '$1');\n }\n\n return fixed;\n });\n}\n\n/**\n * Normalizes whitespace in LaTeX expressions\n * - Removes extra spaces around $ delimiters\n * - Normalizes multiple spaces to single space inside formulas\n *\n * @param text The input string containing LaTeX expressions\n * @returns The string with normalized whitespace\n */\nexport function normalizeLatexSpacing(text: string): string {\n let result = text;\n\n // Remove spaces inside $ delimiters (at the edges)\n result = result.replaceAll(/\\$\\s+/g, '$');\n result = result.replaceAll(/\\s+\\$/g, '$');\n result = result.replaceAll(/\\$\\$\\s+/g, '$$');\n result = result.replaceAll(/\\s+\\$\\$/g, '$$');\n\n // Normalize multiple spaces inside formulas to single space\n result = result.replaceAll(/(\\$\\$[\\s\\S]*?\\$\\$|\\$[\\s\\S]*?\\$)/g, (match) => {\n return match.replaceAll(/\\s{2,}/g, ' ');\n });\n\n return result;\n}\n\n/**\n * Validates all LaTeX expressions in the text\n * Returns detailed information about validation results\n *\n * @param text The input string containing LaTeX expressions\n * @returns Validation results with errors if any\n */\nexport function validateLatexExpressions(text: string): {\n errors: Array<{\n formula: string;\n message: string;\n position: number;\n type: 'display' | 'inline';\n }>;\n totalExpressions: number;\n valid: boolean;\n} {\n const errors: Array<{\n formula: string;\n message: string;\n position: number;\n type: 'display' | 'inline';\n }> = [];\n\n let totalExpressions = 0;\n const pattern = /\\$\\$([\\s\\S]*?)\\$\\$|(?<!\\\\)\\$(?!\\$)([\\s\\S]*?)(?<!\\\\)\\$(?!\\$)/g;\n let match;\n\n while ((match = pattern.exec(text)) !== null) {\n totalExpressions++;\n const formula = match[1] || match[2];\n const isDisplay = match[0].startsWith('$$');\n\n try {\n renderToString(formula, {\n displayMode: isDisplay,\n strict: 'warn',\n throwOnError: true,\n trust: false,\n });\n } catch (error) {\n errors.push({\n formula: formula.slice(0, 50) + (formula.length > 50 ? '...' : ''),\n message: error instanceof Error ? error.message : String(error),\n position: match.index,\n type: isDisplay ? 'display' : 'inline',\n });\n }\n }\n\n return {\n errors,\n totalExpressions,\n valid: errors.length === 0,\n };\n}\n\n/**\n * Handles CJK (Chinese, Japanese, Korean) characters mixed with LaTeX\n * Optionally adds spaces between CJK characters and LaTeX expressions for better rendering\n *\n * @param text The input string\n * @param addSpaces Whether to add spaces between CJK and LaTeX (default: false)\n * @returns The processed string\n */\nexport function handleCJKWithLatex(text: string, addSpaces = false): string {\n if (!addSpaces) return text;\n\n let result = text;\n\n // Add space between CJK character and opening $\n result = result.replaceAll(/([\\u3040-\\u30FF\\u4E00-\\u9FA5])(\\$)/g, '$1 $2');\n\n // Add space between closing $ and CJK character\n result = result.replaceAll(/(\\$)([\\u3040-\\u30FF\\u4E00-\\u9FA5])/g, '$1 $2');\n\n return result;\n}\n\n// ============================================================================\n// Advanced Preprocessing Options\n// ============================================================================\n\nexport interface AdvancedPreprocessOptions {\n /** Add spaces between CJK and LaTeX (default: false, requires handleCJK: true) */\n addCJKSpaces?: boolean;\n /** Convert bracket notation \\[...\\] to $$...$$ (default: true) */\n convertBrackets?: boolean;\n /** Enable currency escaping (default: true) */\n escapeCurrency?: boolean;\n /** Escape mhchem commands (default: true) */\n escapeMhchem?: boolean;\n /** Escape pipe symbols in LaTeX (default: true) */\n escapePipes?: boolean;\n /** Escape underscores in \\text{} (default: true) */\n escapeUnderscores?: boolean;\n /** Automatically fix common LaTeX errors (default: false) */\n fixErrors?: boolean;\n /** Handle CJK characters (default: false) */\n handleCJK?: boolean;\n /** Normalize whitespace (default: false) */\n normalizeSpacing?: boolean;\n /** Throw error on validation failure (default: false, requires validate: true) */\n throwOnValidationError?: boolean;\n /** Validate LaTeX syntax (default: false) */\n validate?: boolean;\n}\n\n/**\n * Comprehensive LaTeX preprocessing with configurable options\n *\n * This is the main preprocessing function that handles:\n * - Currency symbol escaping (e.g., $20 → \\$20)\n * - LaTeX delimiter conversion (\\[...\\] → $$...$$)\n * - Special character escaping (pipes, underscores, mhchem)\n * - Optional error fixing and validation\n * - Optional CJK character handling\n *\n * @param text The input string containing LaTeX and Markdown\n * @param options Configuration options for fine-grained control\n * @returns The preprocessed string\n *\n * @example\n * ```ts\n * // Default behavior (same as old preprocessLaTeX)\n * preprocessLaTeX('向量$90^\\\\circ$,非 $0^\\\\circ$ 和 $180^\\\\circ$')\n *\n * // With custom options\n * preprocessLaTeX(text, {\n * fixErrors: true,\n * validate: true,\n * handleCJK: true\n * })\n * ```\n */\nexport function preprocessLaTeX(text: string, options: AdvancedPreprocessOptions = {}): string {\n const {\n addCJKSpaces = false,\n convertBrackets = true,\n escapeCurrency = true,\n escapeMhchem = true,\n escapePipes = true,\n escapeUnderscores = true,\n fixErrors = false,\n handleCJK = false,\n normalizeSpacing = false,\n throwOnValidationError = false,\n validate = false,\n } = options;\n\n let content = text;\n\n // Phase 1: Currency escaping (if enabled)\n if (escapeCurrency) {\n content = escapeCurrencyDollars(content);\n }\n\n // Phase 2: Bracket conversion (if enabled)\n if (convertBrackets) {\n content = convertLatexDelimiters(content);\n }\n\n // Phase 3: LaTeX-specific escaping\n if (escapeMhchem) {\n content = escapeMhchemCommands(content);\n }\n\n if (escapePipes) {\n content = escapeLatexPipes(content);\n }\n\n if (escapeUnderscores) {\n content = escapeTextUnderscores(content);\n }\n\n // Phase 4: Error fixing (if enabled)\n if (fixErrors) {\n content = fixCommonLaTeXErrors(content);\n }\n\n // Phase 5: Whitespace normalization (if enabled)\n if (normalizeSpacing) {\n content = normalizeLatexSpacing(content);\n }\n\n // Phase 6: CJK handling (if enabled)\n if (handleCJK) {\n content = handleCJKWithLatex(content, addCJKSpaces);\n }\n\n // Phase 7: Validation (if enabled)\n if (validate) {\n const validation = validateLatexExpressions(content);\n if (!validation.valid) {\n const errorMessage = `LaTeX validation failed (${validation.errors.length}/${validation.totalExpressions} expressions have errors):\\n${validation.errors.map((e) => ` - [${e.type}] at position ${e.position}: ${e.message}\\n Formula: ${e.formula}`).join('\\n')}`;\n\n if (throwOnValidationError) {\n throw new Error(errorMessage);\n } else {\n console.warn(errorMessage);\n }\n }\n }\n\n return content;\n}\n\n/**\n * Strict preprocessing mode - enables all safety features and validations\n * Use this when you want maximum correctness and are willing to accept the performance cost\n *\n * @param text The input string\n * @returns The preprocessed string with all features enabled\n *\n * @example\n * ```ts\n * const processed = preprocessLaTeXStrict(userInput)\n * // Enables: error fixing, validation, CJK handling, space normalization\n * ```\n */\nexport function preprocessLaTeXStrict(text: string): string {\n return preprocessLaTeX(text, {\n addCJKSpaces: false, // Usually don't want extra spaces\n convertBrackets: true,\n escapeCurrency: true,\n escapeMhchem: true,\n escapePipes: true,\n escapeUnderscores: true,\n fixErrors: true,\n handleCJK: true,\n normalizeSpacing: true,\n throwOnValidationError: false, // Warn but don't throw\n validate: true,\n });\n}\n\n/**\n * Minimal preprocessing mode - only essential operations\n * Use this for better performance when you control the input\n *\n * @param text The input string\n * @returns The preprocessed string with minimal processing\n *\n * @example\n * ```ts\n * const processed = preprocessLaTeXMinimal(trustedInput)\n * // Only escapes currency and converts brackets\n * ```\n */\nexport function preprocessLaTeXMinimal(text: string): string {\n return preprocessLaTeX(text, {\n convertBrackets: true,\n escapeCurrency: true,\n escapeMhchem: false,\n escapePipes: false,\n escapeUnderscores: false,\n fixErrors: false,\n handleCJK: false,\n normalizeSpacing: false,\n validate: false,\n });\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMarkdownContent.mjs","names":[],"sources":["../../../src/hooks/useMarkdown/useMarkdownContent.ts"],"sourcesContent":["'use client';\n\nimport { useMemo, useRef, useState } from 'react';\n\nimport { useMarkdownContext } from '@/Markdown/components/MarkdownProvider';\n\nimport { isLastFormulaRenderable } from './latex';\nimport { addToCache, contentCache, preprocessMarkdownContent } from './utils';\n\nexport const useMarkdownContent = (children: string): string | undefined => {\n const { animated, enableLatex = true, enableCustomFootnotes, citations } = useMarkdownContext();\n const [validContent, setValidContent] = useState<string>('');\n const prevProcessedContent = useRef<string>('');\n\n const citationsLength = citations?.length || 0;\n\n // Calculate cache key with fewer string concatenations and better performance\n const cacheKey = useMemo(\n () => `${children}|${enableLatex ? 1 : 0}|${enableCustomFootnotes ? 1 : 0}|${citationsLength}`,\n [children, enableLatex, enableCustomFootnotes, citationsLength],\n );\n\n // Process content and use cache to avoid repeated calculations\n return useMemo(() => {\n // Try to get from cache first for best performance\n if (contentCache.has(cacheKey)) {\n return contentCache.get(cacheKey);\n }\n\n // Process new content only if needed\n let processedContent = preprocessMarkdownContent(children, {\n citationsLength,\n enableCustomFootnotes,\n enableLatex,\n });\n\n // Special handling for LaTeX content when animated\n if (animated && enableLatex) {\n const isRenderable = isLastFormulaRenderable(processedContent);\n if (!isRenderable && validContent) {\n processedContent = validContent;\n }\n }\n\n // Only update state if content changed (prevents unnecessary re-renders)\n if (processedContent !== prevProcessedContent.current) {\n setValidContent(processedContent);\n prevProcessedContent.current = processedContent;\n }\n\n // Cache the processed result\n addToCache(cacheKey, processedContent);\n return processedContent;\n }, [\n cacheKey,\n children,\n enableLatex,\n enableCustomFootnotes,\n citationsLength,\n animated,\n validContent,\n ]);\n};\n"],"mappings":";;;;;;AASA,MAAa,sBAAsB,aAAyC;CAC1E,MAAM,EAAE,UAAU,cAAc,MAAM,uBAAuB,cAAc,mBAAmB;CAC9F,MAAM,CAAC,cAAc,mBAAmB,SAAiB,EAAE;CAC3D,MAAM,uBAAuB,OAAe,EAAE;CAE9C,MAAM,kBAAkB,WAAW,UAAU;CAG7C,MAAM,WAAW,cACT,GAAG,SAAS,GAAG,cAAc,IAAI,EAAE,GAAG,wBAAwB,IAAI,EAAE,GAAG,mBAC7E;EAAC;EAAU;EAAa;EAAuB;CAAe,CAChE;CAGA,OAAO,cAAc;EAEnB,IAAI,aAAa,IAAI,QAAQ,GAC3B,OAAO,aAAa,IAAI,QAAQ;EAIlC,IAAI,mBAAmB,0BAA0B,UAAU;GACzD;GACA;GACA;EACF,CAAC;EAGD,IAAI,YAAY;
|
|
1
|
+
{"version":3,"file":"useMarkdownContent.mjs","names":[],"sources":["../../../src/hooks/useMarkdown/useMarkdownContent.ts"],"sourcesContent":["'use client';\n\nimport { useMemo, useRef, useState } from 'react';\n\nimport { useMarkdownContext } from '@/Markdown/components/MarkdownProvider';\n\nimport { isLastFormulaRenderable } from './latex';\nimport { addToCache, contentCache, preprocessMarkdownContent } from './utils';\n\nexport const useMarkdownContent = (children: string): string | undefined => {\n const { animated, enableLatex = true, enableCustomFootnotes, citations } = useMarkdownContext();\n const [validContent, setValidContent] = useState<string>('');\n const prevProcessedContent = useRef<string>('');\n\n const citationsLength = citations?.length || 0;\n\n // Calculate cache key with fewer string concatenations and better performance\n const cacheKey = useMemo(\n () => `${children}|${enableLatex ? 1 : 0}|${enableCustomFootnotes ? 1 : 0}|${citationsLength}`,\n [children, enableLatex, enableCustomFootnotes, citationsLength],\n );\n\n // Process content and use cache to avoid repeated calculations\n return useMemo(() => {\n // Try to get from cache first for best performance\n if (contentCache.has(cacheKey)) {\n return contentCache.get(cacheKey);\n }\n\n // Process new content only if needed\n let processedContent = preprocessMarkdownContent(children, {\n citationsLength,\n enableCustomFootnotes,\n enableLatex,\n });\n\n // Special handling for LaTeX content when animated\n if (animated && enableLatex) {\n const isRenderable = isLastFormulaRenderable(processedContent);\n if (!isRenderable && validContent) {\n processedContent = validContent;\n }\n }\n\n // Only update state if content changed (prevents unnecessary re-renders)\n if (processedContent !== prevProcessedContent.current) {\n setValidContent(processedContent);\n prevProcessedContent.current = processedContent;\n }\n\n // Cache the processed result\n addToCache(cacheKey, processedContent);\n return processedContent;\n }, [\n cacheKey,\n children,\n enableLatex,\n enableCustomFootnotes,\n citationsLength,\n animated,\n validContent,\n ]);\n};\n"],"mappings":";;;;;;AASA,MAAa,sBAAsB,aAAyC;CAC1E,MAAM,EAAE,UAAU,cAAc,MAAM,uBAAuB,cAAc,mBAAmB;CAC9F,MAAM,CAAC,cAAc,mBAAmB,SAAiB,EAAE;CAC3D,MAAM,uBAAuB,OAAe,EAAE;CAE9C,MAAM,kBAAkB,WAAW,UAAU;CAG7C,MAAM,WAAW,cACT,GAAG,SAAS,GAAG,cAAc,IAAI,EAAE,GAAG,wBAAwB,IAAI,EAAE,GAAG,mBAC7E;EAAC;EAAU;EAAa;EAAuB;CAAe,CAChE;CAGA,OAAO,cAAc;EAEnB,IAAI,aAAa,IAAI,QAAQ,GAC3B,OAAO,aAAa,IAAI,QAAQ;EAIlC,IAAI,mBAAmB,0BAA0B,UAAU;GACzD;GACA;GACA;EACF,CAAC;EAGD,IAAI,YAAY,aAEV;OAAA,CADiB,wBAAwB,gBAC7B,KAAK,cACnB,mBAAmB;EAAA;EAKvB,IAAI,qBAAqB,qBAAqB,SAAS;GACrD,gBAAgB,gBAAgB;GAChC,qBAAqB,UAAU;EACjC;EAGA,WAAW,UAAU,gBAAgB;EACrC,OAAO;CACT,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;AACH"}
|
package/es/hooks/useMermaid.mjs
CHANGED
|
@@ -1,133 +1,98 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { prepareInlineMermaidSvg } from "../Mermaid/SyntaxMermaid/prepareInlineSvg.mjs";
|
|
3
|
+
import { createCdnMermaidConfig, renderWithCdnMermaid } from "./useMermaidCdn.mjs";
|
|
4
|
+
import { useEffect, useId, useMemo, useState } from "react";
|
|
5
|
+
import { useThemeMode } from "antd-style";
|
|
6
|
+
import { THEMES, renderMermaidSVG } from "beautiful-mermaid";
|
|
5
7
|
//#region src/hooks/useMermaid.ts
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
/**
|
|
9
|
+
* beautiful-mermaid emits these as CSS custom properties on the SVG root and
|
|
10
|
+
* derives the rest with color-mix(), so pointing them at antd's variables lets
|
|
11
|
+
* the diagram follow the theme through CSS alone — no token subscription, and
|
|
12
|
+
* no re-render (or re-layout) when the appearance changes.
|
|
13
|
+
*/
|
|
14
|
+
const LOBE_THEME_OPTIONS = {
|
|
15
|
+
accent: "var(--ant-color-primary)",
|
|
16
|
+
bg: "var(--ant-color-bg-container)",
|
|
17
|
+
border: "var(--ant-color-border)",
|
|
18
|
+
fg: "var(--ant-color-text)",
|
|
19
|
+
line: "var(--ant-color-text-secondary)",
|
|
20
|
+
muted: "var(--ant-color-text-description)",
|
|
21
|
+
surface: "var(--ant-color-fill-tertiary)",
|
|
22
|
+
transparent: true
|
|
21
23
|
};
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
gantt: { useWidth: 1920 },
|
|
25
|
-
securityLevel,
|
|
26
|
-
startOnLoad: false,
|
|
27
|
-
theme: customTheme || (theme.isDarkMode ? "dark" : "neutral"),
|
|
28
|
-
themeVariables: customTheme ? void 0 : {
|
|
29
|
-
errorBkgColor: theme.colorTextDescription,
|
|
30
|
-
errorTextColor: theme.colorTextDescription,
|
|
31
|
-
fontFamily: theme.fontFamily,
|
|
32
|
-
lineColor: theme.colorTextSecondary,
|
|
33
|
-
mainBkg: theme.colorBgContainer,
|
|
34
|
-
noteBkgColor: theme.colorInfoBg,
|
|
35
|
-
noteTextColor: theme.colorInfoText,
|
|
36
|
-
pie1: theme.geekblue,
|
|
37
|
-
pie2: theme.colorWarning,
|
|
38
|
-
pie3: theme.colorSuccess,
|
|
39
|
-
pie4: theme.colorError,
|
|
40
|
-
primaryBorderColor: theme.colorBorder,
|
|
41
|
-
primaryColor: theme.colorBgContainer,
|
|
42
|
-
primaryTextColor: theme.colorText,
|
|
43
|
-
secondaryBorderColor: theme.colorInfoBorder,
|
|
44
|
-
secondaryColor: theme.colorInfoBg,
|
|
45
|
-
secondaryTextColor: theme.colorInfoText,
|
|
46
|
-
tertiaryBorderColor: theme.colorSuccessBorder,
|
|
47
|
-
tertiaryColor: theme.colorSuccessBg,
|
|
48
|
-
tertiaryTextColor: theme.colorSuccessText,
|
|
49
|
-
textColor: theme.colorText
|
|
50
|
-
}
|
|
51
|
-
});
|
|
24
|
+
const isNamedTheme = (theme) => !!theme && theme !== "lobe-theme" && theme in THEMES;
|
|
25
|
+
const createMermaidOptions = (customTheme) => isNamedTheme(customTheme) ? THEMES[customTheme] : LOBE_THEME_OPTIONS;
|
|
52
26
|
/**
|
|
53
|
-
*
|
|
27
|
+
* beautiful-mermaid covers six diagram types; anything else throws here and is
|
|
28
|
+
* handed to the CDN-loaded upstream mermaid instead.
|
|
54
29
|
*/
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
theme.colorBorder,
|
|
72
|
-
theme.colorInfoBorder,
|
|
73
|
-
theme.colorSuccessBorder,
|
|
74
|
-
theme.colorSuccessBg,
|
|
75
|
-
theme.colorSuccessText,
|
|
76
|
-
theme.colorText,
|
|
77
|
-
customTheme,
|
|
78
|
-
securityLevel
|
|
79
|
-
]);
|
|
80
|
-
const cacheKey = useMemo(() => {
|
|
81
|
-
const hash = content.length < 1e4 ? content : Md5.hashStr(content);
|
|
82
|
-
return [
|
|
83
|
-
id,
|
|
84
|
-
customTheme || (theme.isDarkMode ? "d" : "l"),
|
|
85
|
-
hash
|
|
86
|
-
].filter(Boolean).join("-");
|
|
87
|
-
}, [
|
|
88
|
-
content,
|
|
89
|
-
id,
|
|
90
|
-
theme.isDarkMode,
|
|
91
|
-
customTheme
|
|
92
|
-
]);
|
|
30
|
+
const renderMermaid = (content, scopeId, customTheme) => {
|
|
31
|
+
if (!content) return { svg: "" };
|
|
32
|
+
try {
|
|
33
|
+
const svg = renderMermaidSVG(content, createMermaidOptions(customTheme));
|
|
34
|
+
return { svg: prepareInlineMermaidSvg(svg, scopeId) };
|
|
35
|
+
} catch {
|
|
36
|
+
return {
|
|
37
|
+
error: "unsupported",
|
|
38
|
+
svg: ""
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const useCdnMermaidFallback = (content, { enabled, theme: customTheme }) => {
|
|
43
|
+
const { isDarkMode } = useThemeMode();
|
|
44
|
+
const reactId = useId();
|
|
45
|
+
const [result, setResult] = useState({ svg: "" });
|
|
93
46
|
useEffect(() => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
cachedPromise.then((svg) => {
|
|
97
|
-
setData(svg);
|
|
98
|
-
}).catch(() => {});
|
|
47
|
+
if (!enabled || !content) {
|
|
48
|
+
setResult({ svg: "" });
|
|
99
49
|
return;
|
|
100
50
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
})();
|
|
115
|
-
mermaidCache.set(cacheKey, renderPromise);
|
|
116
|
-
cleanupCache();
|
|
117
|
-
renderPromise.then((svg) => {
|
|
118
|
-
if (mermaidCache.get(cacheKey) === renderPromise) setData(svg);
|
|
51
|
+
let active = true;
|
|
52
|
+
setResult({
|
|
53
|
+
loading: true,
|
|
54
|
+
svg: ""
|
|
55
|
+
});
|
|
56
|
+
const config = createCdnMermaidConfig(isDarkMode, isNamedTheme(customTheme) ? customTheme : void 0);
|
|
57
|
+
renderWithCdnMermaid(content, `mermaid-cdn-${reactId.replaceAll(":", "")}`, config).then((svg) => {
|
|
58
|
+
if (!active) return;
|
|
59
|
+
setResult(svg ? { svg } : {
|
|
60
|
+
error: "Failed to render diagram",
|
|
61
|
+
svg: ""
|
|
62
|
+
});
|
|
119
63
|
}).catch(() => {
|
|
120
|
-
if (
|
|
64
|
+
if (active) setResult({
|
|
65
|
+
error: "Failed to render diagram",
|
|
66
|
+
svg: ""
|
|
67
|
+
});
|
|
121
68
|
});
|
|
69
|
+
return () => {
|
|
70
|
+
active = false;
|
|
71
|
+
};
|
|
122
72
|
}, [
|
|
123
|
-
|
|
73
|
+
enabled,
|
|
124
74
|
content,
|
|
125
|
-
|
|
126
|
-
|
|
75
|
+
isDarkMode,
|
|
76
|
+
customTheme,
|
|
77
|
+
reactId
|
|
78
|
+
]);
|
|
79
|
+
return result;
|
|
80
|
+
};
|
|
81
|
+
const useMermaid = (content, { theme: customTheme } = {}) => {
|
|
82
|
+
const reactId = useId();
|
|
83
|
+
const scopeId = useMemo(() => `mermaid-${reactId.replaceAll(":", "")}`, [reactId]);
|
|
84
|
+
const primary = useMemo(() => renderMermaid(content, scopeId, customTheme), [
|
|
85
|
+
content,
|
|
86
|
+
scopeId,
|
|
87
|
+
customTheme
|
|
127
88
|
]);
|
|
128
|
-
|
|
89
|
+
const fallback = useCdnMermaidFallback(content, {
|
|
90
|
+
enabled: Boolean(primary.error),
|
|
91
|
+
theme: customTheme
|
|
92
|
+
});
|
|
93
|
+
return primary.error ? fallback : primary;
|
|
129
94
|
};
|
|
130
95
|
//#endregion
|
|
131
|
-
export {
|
|
96
|
+
export { createMermaidOptions, renderMermaid, useCdnMermaidFallback, useMermaid };
|
|
132
97
|
|
|
133
98
|
//# sourceMappingURL=useMermaid.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMermaid.mjs","names":[],"sources":["../../src/hooks/useMermaid.ts"],"sourcesContent":["'use client';\n\nimport {
|
|
1
|
+
{"version":3,"file":"useMermaid.mjs","names":[],"sources":["../../src/hooks/useMermaid.ts"],"sourcesContent":["'use client';\n\nimport { useThemeMode } from 'antd-style';\nimport { renderMermaidSVG, type RenderOptions, type ThemeName, THEMES } from 'beautiful-mermaid';\nimport { useEffect, useId, useMemo, useState } from 'react';\n\nimport { prepareInlineMermaidSvg } from '@/Mermaid/SyntaxMermaid/prepareInlineSvg';\n\nimport { createCdnMermaidConfig, renderWithCdnMermaid } from './useMermaidCdn';\n\nexport type MermaidThemeName = 'lobe-theme' | ThemeName;\n\nexport interface MermaidRenderResult {\n error?: string;\n loading?: boolean;\n svg: string;\n}\n\n/**\n * beautiful-mermaid emits these as CSS custom properties on the SVG root and\n * derives the rest with color-mix(), so pointing them at antd's variables lets\n * the diagram follow the theme through CSS alone — no token subscription, and\n * no re-render (or re-layout) when the appearance changes.\n */\nconst LOBE_THEME_OPTIONS: RenderOptions = {\n accent: 'var(--ant-color-primary)',\n bg: 'var(--ant-color-bg-container)',\n border: 'var(--ant-color-border)',\n fg: 'var(--ant-color-text)',\n line: 'var(--ant-color-text-secondary)',\n muted: 'var(--ant-color-text-description)',\n surface: 'var(--ant-color-fill-tertiary)',\n transparent: true,\n};\n\nconst isNamedTheme = (theme?: MermaidThemeName): theme is ThemeName =>\n !!theme && theme !== 'lobe-theme' && theme in THEMES;\n\nexport const createMermaidOptions = (customTheme?: MermaidThemeName): RenderOptions =>\n isNamedTheme(customTheme) ? THEMES[customTheme]! : LOBE_THEME_OPTIONS;\n\n/**\n * beautiful-mermaid covers six diagram types; anything else throws here and is\n * handed to the CDN-loaded upstream mermaid instead.\n */\nexport const renderMermaid = (\n content: string,\n scopeId: string,\n customTheme?: MermaidThemeName,\n): MermaidRenderResult => {\n if (!content) return { svg: '' };\n try {\n const svg = renderMermaidSVG(content, createMermaidOptions(customTheme));\n return { svg: prepareInlineMermaidSvg(svg, scopeId) };\n } catch {\n return { error: 'unsupported', svg: '' };\n }\n};\n\nexport const useCdnMermaidFallback = (\n content: string,\n { enabled, theme: customTheme }: { enabled: boolean; theme?: MermaidThemeName },\n): MermaidRenderResult => {\n const { isDarkMode } = useThemeMode();\n const reactId = useId();\n const [result, setResult] = useState<MermaidRenderResult>({ svg: '' });\n\n useEffect(() => {\n if (!enabled || !content) {\n setResult({ svg: '' });\n return;\n }\n\n let active = true;\n setResult({ loading: true, svg: '' });\n\n const config = createCdnMermaidConfig(\n isDarkMode,\n isNamedTheme(customTheme) ? customTheme : undefined,\n );\n\n renderWithCdnMermaid(content, `mermaid-cdn-${reactId.replaceAll(':', '')}`, config)\n .then((svg) => {\n if (!active) return;\n setResult(svg ? { svg } : { error: 'Failed to render diagram', svg: '' });\n })\n .catch(() => {\n if (active) setResult({ error: 'Failed to render diagram', svg: '' });\n });\n\n return () => {\n active = false;\n };\n }, [enabled, content, isDarkMode, customTheme, reactId]);\n\n return result;\n};\n\nexport const useMermaid = (\n content: string,\n { theme: customTheme }: { theme?: MermaidThemeName } = {},\n): MermaidRenderResult => {\n const reactId = useId();\n const scopeId = useMemo(() => `mermaid-${reactId.replaceAll(':', '')}`, [reactId]);\n\n const primary = useMemo(\n () => renderMermaid(content, scopeId, customTheme),\n [content, scopeId, customTheme],\n );\n\n const fallback = useCdnMermaidFallback(content, {\n enabled: Boolean(primary.error),\n theme: customTheme,\n });\n\n return primary.error ? fallback : primary;\n};\n"],"mappings":";;;;;;;;;;;;;AAwBA,MAAM,qBAAoC;CACxC,QAAQ;CACR,IAAI;CACJ,QAAQ;CACR,IAAI;CACJ,MAAM;CACN,OAAO;CACP,SAAS;CACT,aAAa;AACf;AAEA,MAAM,gBAAgB,UACpB,CAAC,CAAC,SAAS,UAAU,gBAAgB,SAAS;AAEhD,MAAa,wBAAwB,gBACnC,aAAa,WAAW,IAAI,OAAO,eAAgB;;;;;AAMrD,MAAa,iBACX,SACA,SACA,gBACwB;CACxB,IAAI,CAAC,SAAS,OAAO,EAAE,KAAK,GAAG;CAC/B,IAAI;EACF,MAAM,MAAM,iBAAiB,SAAS,qBAAqB,WAAW,CAAC;EACvE,OAAO,EAAE,KAAK,wBAAwB,KAAK,OAAO,EAAE;CACtD,QAAQ;EACN,OAAO;GAAE,OAAO;GAAe,KAAK;EAAG;CACzC;AACF;AAEA,MAAa,yBACX,SACA,EAAE,SAAS,OAAO,kBACM;CACxB,MAAM,EAAE,eAAe,aAAa;CACpC,MAAM,UAAU,MAAM;CACtB,MAAM,CAAC,QAAQ,aAAa,SAA8B,EAAE,KAAK,GAAG,CAAC;CAErE,gBAAgB;EACd,IAAI,CAAC,WAAW,CAAC,SAAS;GACxB,UAAU,EAAE,KAAK,GAAG,CAAC;GACrB;EACF;EAEA,IAAI,SAAS;EACb,UAAU;GAAE,SAAS;GAAM,KAAK;EAAG,CAAC;EAEpC,MAAM,SAAS,uBACb,YACA,aAAa,WAAW,IAAI,cAAc,KAAA,CAC5C;EAEA,qBAAqB,SAAS,eAAe,QAAQ,WAAW,KAAK,EAAE,KAAK,MAAM,CAAC,CAChF,MAAM,QAAQ;GACb,IAAI,CAAC,QAAQ;GACb,UAAU,MAAM,EAAE,IAAI,IAAI;IAAE,OAAO;IAA4B,KAAK;GAAG,CAAC;EAC1E,CAAC,CAAC,CACD,YAAY;GACX,IAAI,QAAQ,UAAU;IAAE,OAAO;IAA4B,KAAK;GAAG,CAAC;EACtE,CAAC;EAEH,aAAa;GACX,SAAS;EACX;CACF,GAAG;EAAC;EAAS;EAAS;EAAY;EAAa;CAAO,CAAC;CAEvD,OAAO;AACT;AAEA,MAAa,cACX,SACA,EAAE,OAAO,gBAA8C,CAAC,MAChC;CACxB,MAAM,UAAU,MAAM;CACtB,MAAM,UAAU,cAAc,WAAW,QAAQ,WAAW,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;CAEjF,MAAM,UAAU,cACR,cAAc,SAAS,SAAS,WAAW,GACjD;EAAC;EAAS;EAAS;CAAW,CAChC;CAEA,MAAM,WAAW,sBAAsB,SAAS;EAC9C,SAAS,QAAQ,QAAQ,KAAK;EAC9B,OAAO;CACT,CAAC;CAED,OAAO,QAAQ,QAAQ,WAAW;AACpC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/hooks/useMermaidCdn.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Point the fallback loader at a mirror, or at a self-hosted copy for offline
|
|
4
|
+
* and strict-CSP deployments. Resets any in-flight load.
|
|
5
|
+
*/
|
|
6
|
+
declare const setMermaidCdnUrl: (url: string) => void;
|
|
7
|
+
declare const getMermaidCdnUrl: () => string;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { getMermaidCdnUrl, setMermaidCdnUrl };
|
|
10
|
+
//# sourceMappingURL=useMermaidCdn.d.mts.map
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/hooks/useMermaidCdn.ts
|
|
3
|
+
let mermaidCdnUrl = "https://esm.sh/mermaid@11";
|
|
4
|
+
let mermaidPromise = null;
|
|
5
|
+
/**
|
|
6
|
+
* Point the fallback loader at a mirror, or at a self-hosted copy for offline
|
|
7
|
+
* and strict-CSP deployments. Resets any in-flight load.
|
|
8
|
+
*/
|
|
9
|
+
const setMermaidCdnUrl = (url) => {
|
|
10
|
+
if (url === mermaidCdnUrl) return;
|
|
11
|
+
mermaidCdnUrl = url;
|
|
12
|
+
mermaidPromise = null;
|
|
13
|
+
};
|
|
14
|
+
const getMermaidCdnUrl = () => mermaidCdnUrl;
|
|
15
|
+
const loadCdnMermaid = () => {
|
|
16
|
+
if (typeof window === "undefined") return Promise.resolve(null);
|
|
17
|
+
mermaidPromise ??= import(
|
|
18
|
+
/* @vite-ignore */
|
|
19
|
+
mermaidCdnUrl
|
|
20
|
+
).then((mod) => mod.default ?? mod).catch(() => null);
|
|
21
|
+
return mermaidPromise;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Upstream mermaid runs colour maths over themeVariables, so it needs literal
|
|
25
|
+
* values rather than var() references. Reading antd's CSS variables here keeps
|
|
26
|
+
* the cost off the render path — no theme context subscription, and it only
|
|
27
|
+
* runs for the diagram types that actually fall back to the CDN.
|
|
28
|
+
*/
|
|
29
|
+
const readCssVars = (names) => {
|
|
30
|
+
const result = {};
|
|
31
|
+
if (typeof document === "undefined") return result;
|
|
32
|
+
const computed = globalThis.getComputedStyle(document.documentElement);
|
|
33
|
+
for (const [key, variable] of Object.entries(names)) result[key] = computed.getPropertyValue(variable).trim() || void 0;
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
const createCdnMermaidConfig = (isDarkMode, customTheme) => {
|
|
37
|
+
const token = readCssVars({
|
|
38
|
+
border: "--ant-color-border",
|
|
39
|
+
error: "--ant-color-error",
|
|
40
|
+
fontFamily: "--ant-font-family",
|
|
41
|
+
fontFamilyCode: "--ant-font-family-code",
|
|
42
|
+
infoBg: "--ant-color-info-bg",
|
|
43
|
+
infoBorder: "--ant-color-info-border",
|
|
44
|
+
infoText: "--ant-color-info-text",
|
|
45
|
+
primary: "--ant-color-primary",
|
|
46
|
+
success: "--ant-color-success",
|
|
47
|
+
successBg: "--ant-color-success-bg",
|
|
48
|
+
successBorder: "--ant-color-success-border",
|
|
49
|
+
successText: "--ant-color-success-text",
|
|
50
|
+
text: "--ant-color-text",
|
|
51
|
+
textDescription: "--ant-color-text-description",
|
|
52
|
+
textSecondary: "--ant-color-text-secondary",
|
|
53
|
+
bgContainer: "--ant-color-bg-container",
|
|
54
|
+
warning: "--ant-color-warning"
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
fontFamily: token.fontFamilyCode,
|
|
58
|
+
gantt: { useWidth: 1920 },
|
|
59
|
+
securityLevel: "strict",
|
|
60
|
+
startOnLoad: false,
|
|
61
|
+
theme: customTheme || (isDarkMode ? "dark" : "neutral"),
|
|
62
|
+
themeVariables: customTheme ? void 0 : {
|
|
63
|
+
errorBkgColor: token.textDescription,
|
|
64
|
+
errorTextColor: token.textDescription,
|
|
65
|
+
fontFamily: token.fontFamily,
|
|
66
|
+
lineColor: token.textSecondary,
|
|
67
|
+
mainBkg: token.bgContainer,
|
|
68
|
+
noteBkgColor: token.infoBg,
|
|
69
|
+
noteTextColor: token.infoText,
|
|
70
|
+
pie1: token.primary,
|
|
71
|
+
pie2: token.warning,
|
|
72
|
+
pie3: token.success,
|
|
73
|
+
pie4: token.error,
|
|
74
|
+
primaryBorderColor: token.border,
|
|
75
|
+
primaryColor: token.bgContainer,
|
|
76
|
+
primaryTextColor: token.text,
|
|
77
|
+
secondaryBorderColor: token.infoBorder,
|
|
78
|
+
secondaryColor: token.infoBg,
|
|
79
|
+
secondaryTextColor: token.infoText,
|
|
80
|
+
tertiaryBorderColor: token.successBorder,
|
|
81
|
+
tertiaryColor: token.successBg,
|
|
82
|
+
tertiaryTextColor: token.successText,
|
|
83
|
+
textColor: token.text
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
const renderWithCdnMermaid = async (content, id, config) => {
|
|
88
|
+
const mermaid = await loadCdnMermaid();
|
|
89
|
+
if (!mermaid) return "";
|
|
90
|
+
mermaid.initialize(config);
|
|
91
|
+
const { svg } = await mermaid.render(id, content);
|
|
92
|
+
return svg;
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
export { createCdnMermaidConfig, getMermaidCdnUrl, loadCdnMermaid, renderWithCdnMermaid, setMermaidCdnUrl };
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=useMermaidCdn.mjs.map
|