aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/mdx.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/mdx.tsx')
-rw-r--r--src/components/mdx.tsx90
1 files changed, 90 insertions, 0 deletions
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}
+ />
+ ),
+};