Use custom anchor in markdown

Sascha created

The custom anchor will be more readable in dark mode.
Also it will supports linking within the SPA.

Change summary

webui/src/components/Content/AnchorTag.tsx | 38 ++++++++++++++++++++++++
webui/src/components/Content/index.tsx     |  2 +
2 files changed, 40 insertions(+)

Detailed changes

webui/src/components/Content/AnchorTag.tsx 🔗

@@ -0,0 +1,38 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+
+import { makeStyles } from '@material-ui/core/styles';
+
+const useStyles = makeStyles((theme) => ({
+  tag: {
+    color: theme.palette.text.secondary,
+  },
+}));
+
+const AnchorTag = ({ children, href }: React.HTMLProps<HTMLAnchorElement>) => {
+  const classes = useStyles();
+  const origin = window.location.origin;
+  const destination = href === undefined ? '' : href;
+  const isInternalLink =
+    destination.startsWith('/') || destination.startsWith(origin);
+  const internalDestination = destination.replace(origin, '');
+  const internalLink = (
+    <Link className={classes.tag} to={internalDestination}>
+      {children}
+    </Link>
+  );
+  const externalLink = (
+    <a
+      className={classes.tag}
+      href={destination}
+      target="_blank"
+      rel="noopener noreferrer"
+    >
+      {children}
+    </a>
+  );
+
+  return isInternalLink ? internalLink : externalLink;
+};
+
+export default AnchorTag;

webui/src/components/Content/index.tsx 🔗

@@ -5,6 +5,7 @@ import parse from 'remark-parse';
 import remark2react from 'remark-react';
 import unified from 'unified';
 
+import AnchorTag from './AnchorTag';
 import BlockQuoteTag from './BlockQuoteTag';
 import ImageTag from './ImageTag';
 import PreTag from './PreTag';
@@ -19,6 +20,7 @@ const Content: React.FC<Props> = ({ markdown }: Props) => {
       remarkReactComponents: {
         img: ImageTag,
         pre: PreTag,
+        a: AnchorTag,
         blockquote: BlockQuoteTag,
       },
     })