Yuki Takei 3 лет назад
Родитель
Сommit
64f549a29c

+ 49 - 0
packages/app/src/components/ReactMarkdownComponents/Header.tsx

@@ -0,0 +1,49 @@
+import { Element } from 'react-markdown/lib/rehype-filter';
+
+import { NextLink } from './NextLink';
+
+
+type EditLinkProps = {
+  line?: number,
+}
+
+/**
+ * Inner FC to display edit link icon
+ */
+const EditLink = (props: EditLinkProps): JSX.Element => {
+  const isDisabled = props.line == null;
+
+  return (
+    <span className="revision-head-edit-button">
+      <a href="#edit" aria-disabled={isDisabled} onClick={() => console.log(`TODO: Jump to the line '${props.line}'`)}>
+        <i className="icon-note"></i>
+      </a>
+    </span>
+  );
+};
+
+
+type HeaderProps = {
+  children: React.ReactNode,
+  node: Element,
+  level: number,
+  id?: string,
+}
+
+export const Header = (props: HeaderProps): JSX.Element => {
+  const {
+    node, id, children, level,
+  } = props;
+
+  const CustomTag = `h${level}` as keyof JSX.IntrinsicElements;
+
+  return (
+    <CustomTag id={id} className="revision-head">
+      {children}
+      <NextLink href={`#${id}`} className="revision-head-link">
+        <span className="icon-link"></span>
+      </NextLink>
+      <EditLink line={node.position?.start.line} />
+    </CustomTag>
+  );
+};

+ 4 - 0
packages/app/src/services/renderer/growi-renderer.tsx

@@ -6,6 +6,7 @@ import emoji from 'remark-emoji';
 import footnotes from 'remark-footnotes';
 import gfm from 'remark-gfm';
 
+import { Header } from '~/components/ReactMarkdownComponents/Header';
 import { NextLink } from '~/components/ReactMarkdownComponents/NextLink';
 import { GrowiRendererConfig, RendererSettings } from '~/interfaces/services/renderer';
 import loggerFactory from '~/utils/logger';
@@ -218,6 +219,9 @@ const generateCommonOptions: ReactMarkdownOptionsGenerator = (
     rehypePlugins: [slug],
     components: {
       a: NextLink,
+      h1: Header,
+      h2: Header,
+      h3: Header,
     },
   };
 };