diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/atoms/figure/figure.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/heading/heading.tsx | 2 | ||||
| -rw-r--r-- | src/components/atoms/lists/list/list.tsx | 12 | ||||
| -rw-r--r-- | src/components/mdx.tsx | 90 |
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} + /> + ), +}; |
