import Image from 'next/image';
import Link from 'next/link';
import Balancer from 'react-wrap-balancer';
import { Callout } from '@/components/callout';
import { CodeBlock } from '@/components/code-block';
import { TableOfContents } from '@/components/table-of-contents';
import { Video } from '@/components/video';
import { cn } from '@/lib/utils';
/**
* Use for internal links and for external links and anchors
* and open external links in a new tab
*/
function a({ href, children }: React.HTMLProps) {
if (href && href.startsWith('/')) {
return {children};
}
if (href && href.startsWith('#')) {
return {children};
}
return (
{children}
);
}
/**
* Use div instead of p elements since p elements have restrictions on what
* elements can be nested inside them
*/
function p(props: React.HTMLProps) {
return ;
}
/**
* Image component that uses next/image, with optional caption and width/height
* Example usage: \!\[alt text {{ w: 600, h: 300, cap: "caption text" }}](/path/to/image)
*/
function img({ src, alt }: React.HTMLProps) {
const _alt = (alt?.split('{')[0].trim() ?? alt) || '';
const props = alt?.split('{')[1];
const width = parseInt(props?.match(/w:\s*(\d+)/)?.[1] ?? '700');
const height = parseInt(props?.match(/h:\s*(\d+)/)?.[1] ?? '400');
const caption = props?.match(/cap:\s*"(.*?)"/)?.[1];
return (
{caption && (
{caption}
)}
);
}
/**
* Code block component with copy button
*/
function pre({ children }: React.HTMLProps) {
return {children};
}
export const MDXComponents = { a, p, img, pre, TableOfContents, Callout, Video };