From 0ac690339083f01a0b12a74ec117eeccd055e932 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Wed, 22 Nov 2023 17:45:03 +0100
Subject: refactor(components,pages): extract MDX components mapping from pages

Instead of repeating the overriding on each pages, we should define
it in one place and reuse it in pages.
By default it is not possible to override native HTML tags with MDX
so I added a plugin in next config to allow it.
---
 src/components/mdx.tsx | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 src/components/mdx.tsx

(limited to 'src/components/mdx.tsx')

diff --git a/src/components/mdx.tsx b/src/components/mdx.tsx
new file mode 100644
index 0000000..f11dda5
--- /dev/null
+++ b/src/components/mdx.tsx
@@ -0,0 +1,90 @@
+import type { MDXComponents } from 'mdx/types';
+import NextImage from 'next/image';
+import type { AnchorHTMLAttributes, ImgHTMLAttributes, ReactNode } from 'react';
+import { Figure, Heading, Link, List, ListItem } from './atoms';
+import { Code, Grid } from './molecules';
+
+const Anchor = ({
+  children = '',
+  href = '',
+  hrefLang,
+  rel,
+  ...props
+}: AnchorHTMLAttributes<HTMLAnchorElement>) => (
+  <Link
+    {...props}
+    isExternal={rel?.includes('external')}
+    href={href}
+    lang={hrefLang}
+    rel={rel}
+  >
+    {children}
+  </Link>
+);
+
+const Img = ({
+  alt,
+  src,
+  height,
+  placeholder,
+  width,
+  ...props
+}: ImgHTMLAttributes<HTMLImageElement>) => {
+  if (src)
+    return (
+      <NextImage
+        {...props}
+        alt={alt ?? ''}
+        height={typeof height === 'string' ? Number(height) : height}
+        src={src}
+        width={typeof width === 'string' ? Number(width) : width}
+      />
+    );
+
+  // eslint-disable-next-line @next/next/no-img-element
+  return <img {...props} alt={alt} height={height} src={src} width={width} />;
+};
+
+const Gallery = ({ children }: { children: ReactNode[] }) => (
+  <Grid
+    // eslint-disable-next-line react/jsx-no-literals
+    gap="sm"
+    items={children.map((child, index) => {
+      return { id: `${index}`, item: child };
+    })}
+    // eslint-disable-next-line react/jsx-no-literals
+    sizeMin="250px"
+  />
+);
+
+export const mdxComponents: MDXComponents = {
+  a: Anchor,
+  Code,
+  figure: ({ ref, ...props }) => <Figure {...props} />,
+  Figure,
+  Gallery,
+  h1: ({ ref, ...props }) => <Heading {...props} level={1} />,
+  h2: ({ ref, ...props }) => <Heading {...props} level={2} />,
+  h3: ({ ref, ...props }) => <Heading {...props} level={3} />,
+  h4: ({ ref, ...props }) => <Heading {...props} level={4} />,
+  h5: ({ ref, ...props }) => <Heading {...props} level={5} />,
+  h6: ({ ref, ...props }) => <Heading {...props} level={6} />,
+  img: Img,
+  li: ({ ref, ...props }) => <ListItem {...props} />,
+  Link,
+  ol: ({ ref, ...props }) => (
+    <List
+      // eslint-disable-next-line react/jsx-no-literals
+      spacing="2xs"
+      {...props}
+      isOrdered
+    />
+  ),
+  ul: ({ ref, ...props }) => (
+    <List
+      // eslint-disable-next-line react/jsx-no-literals
+      spacing="2xs"
+      {...props}
+    />
+  ),
+};
-- 
cgit v1.2.3

