diff --git a/packages/console/src/components/Markdown/index.tsx b/packages/console/src/components/Markdown/index.tsx
index efc7b7b79..fc56bc518 100644
--- a/packages/console/src/components/Markdown/index.tsx
+++ b/packages/console/src/components/Markdown/index.tsx
@@ -1,5 +1,6 @@
+import { conditionalString, Optional } from '@silverhand/essentials';
import classNames from 'classnames';
-import React from 'react';
+import React, { memo } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
@@ -12,29 +13,57 @@ type Props = {
children: string;
};
-const Markdown = ({ className, children }: Props) => (
- {
- const [, codeBlockType] = /language-(\w+)/.exec(className ?? '') ?? [];
+const Markdown = ({ className, children }: Props) => {
+ const tocIdSet = React.useRef>(new Set());
- return inline ? (
-
- {children}
-
- ) : (
-
- );
- },
- img: ({ src, alt }) => {
- return ;
- },
- }}
- >
- {children}
-
-);
+ const generateTocId = (text: string): Optional => {
+ const resolveIdCollision = (kebabCaseString: string, index = 0): string => {
+ const result = `${kebabCaseString}${conditionalString(index && `-${index}`)}`;
-export default Markdown;
+ if (!tocIdSet.current.has(result)) {
+ tocIdSet.current.add(result);
+
+ return result;
+ }
+
+ return resolveIdCollision(kebabCaseString, index + 1);
+ };
+
+ const initialKebabCaseString = text.replace(/\s/g, '-').toLowerCase();
+
+ return resolveIdCollision(initialKebabCaseString);
+ };
+
+ return (
+ {
+ const [, codeBlockType] = /language-(\w+)/.exec(className ?? '') ?? [];
+
+ return inline ? (
+
+ {children}
+
+ ) : (
+
+ );
+ },
+ img: ({ src, alt }) => {
+ return ;
+ },
+ h1: ({ children }) => {children}
,
+ h2: ({ children }) => {children}
,
+ h3: ({ children }) => {children}
,
+ h4: ({ children }) => {children}
,
+ h5: ({ children }) => {children}
,
+ h6: ({ children }) => {children}
,
+ }}
+ >
+ {children}
+
+ );
+};
+
+export default memo(Markdown);