aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/atoms/figure/figure.tsx2
-rw-r--r--src/components/atoms/heading/heading.tsx2
-rw-r--r--src/components/atoms/lists/list/list.tsx12
-rw-r--r--src/components/mdx.tsx90
4 files changed, 98 insertions, 8 deletions
diff --git a/src/components/atoms/figure/figure.tsx b/src/components/atoms/figure/figure.tsx
index 4dd5b10..7d63259 100644
--- a/src/components/atoms/figure/figure.tsx
+++ b/src/components/atoms/figure/figure.tsx
@@ -11,7 +11,7 @@ export type FigureProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
/**
* The contents (ie. an image, illustration, diagram, code snippet, etc.).
*/
- children: ReactNode;
+ children?: ReactNode;
/**
* A figure caption.
*/
diff --git a/src/components/atoms/heading/heading.tsx b/src/components/atoms/heading/heading.tsx
index 6cdb578..d8c58d1 100644
--- a/src/components/atoms/heading/heading.tsx
+++ b/src/components/atoms/heading/heading.tsx
@@ -14,7 +14,7 @@ export type HeadingProps = HTMLAttributes<HTMLHeadingElement> & {
/**
* The heading body.
*/
- children: ReactNode;
+ children?: ReactNode;
/**
* Use an heading element or only its styles.
*
diff --git a/src/components/atoms/lists/list/list.tsx b/src/components/atoms/lists/list/list.tsx
index 6e58433..61d2216 100644
--- a/src/components/atoms/lists/list/list.tsx
+++ b/src/components/atoms/lists/list/list.tsx
@@ -16,14 +16,14 @@ type UnorderedListProps = Omit<HTMLAttributes<HTMLUListElement>, 'children'>;
type BaseListProps<O extends boolean, H extends boolean> = O extends true
? OrderedListProps
: H extends true
- ? OrderedListProps
- : UnorderedListProps;
+ ? OrderedListProps
+ : UnorderedListProps;
type AdditionalProps<O extends boolean, H extends boolean> = {
/**
- * An array of list items.
+ * The list items.
*/
- children: ReactNode;
+ children?: ReactNode;
/**
* Should the items marker be hidden?
*
@@ -109,8 +109,8 @@ const ListWithRef = <O extends boolean, H extends boolean>(
O extends true
? HTMLOListElement
: H extends true
- ? HTMLOListElement
- : HTMLUListElement
+ ? HTMLOListElement
+ : HTMLUListElement
>
) => {
const itemSpacing = spacing === null ? 0 : `var(--spacing-${spacing})`;
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}
+ />
+ ),
+};