1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-06-27 17:25:43 -04:00
Files
jarv.is/mdx-components.tsx

126 lines
4.6 KiB
TypeScript

import NextImage from "next/image";
import Link from "@/components/link";
import CodeBlock from "@/components/code-block";
import HeadingAnchor from "@/components/heading-anchor";
import Video from "@/components/video";
import ImageDiff from "./components/image-diff";
import Tweet from "@/components/third-party/tweet";
import YouTube from "@/components/third-party/youtube";
import Gist from "@/components/third-party/gist";
import CodePen from "@/components/third-party/codepen";
import { cn } from "@/lib/utils";
import type { MDXComponents } from "mdx/types";
export const useMDXComponents = (components: MDXComponents): MDXComponents => {
return {
...components,
a: Link,
pre: ({ className, ...rest }) => <CodeBlock className={cn("my-5 w-full font-mono text-sm", className)} {...rest} />,
code: ({ className, ...rest }) => (
// only applies to inline code, *not* highlighted code blocks!
<code
className={cn("bg-muted relative rounded-sm px-[0.3rem] py-[0.2rem] text-sm font-medium", className)}
{...rest}
/>
),
img: ({ src, className, ...rest }) => (
<NextImage
src={src}
width={typeof src === "object" && "width" in src && src.width > 896 ? 896 : undefined} // => var(--container-4xl)
className={cn(
"mx-auto my-8 block h-auto max-w-full rounded-md",
"[&+em]:text-muted-foreground [&+em]:-mt-4 [&+em]:block [&+em]:text-center [&+em]:text-[0.875em] [&+em]:leading-normal [&+em]:font-medium [&+em]:not-italic",
className
)}
{...rest}
/>
),
figure: ({ className, ...rest }) => <figure className={cn("my-8 *:my-0", className)} {...rest} />,
figcaption: ({ className, ...rest }) => (
<figcaption className={cn("text-muted-foreground mt-3.5 text-[0.875em] leading-snug", className)} {...rest} />
),
blockquote: ({ className, ...rest }) => (
<blockquote className={cn("text-muted-foreground mt-6 border-l-4 pl-4", className)} {...rest} />
),
h1: ({ className, id, children, ...rest }) => (
<h1
className={cn(
"group mt-6 mb-4 scroll-mt-4 text-3xl leading-snug font-extrabold md:text-4xl [&_strong]:font-black [&+*]:mt-0",
className
)}
id={id}
tabIndex={-1}
{...rest}
>
{children}
{id && <HeadingAnchor id={id} title={children} className="opacity-0 group-hover:opacity-100 max-md:hidden" />}
</h1>
),
h2: ({ className, id, children, ...rest }) => (
<h2
className={cn(
"group mt-6 mb-4 scroll-mt-4 text-xl leading-snug font-bold first:mt-0 md:text-2xl [&_code]:text-[0.875em] [&_strong]:font-extrabold [&+*]:mt-0",
className
)}
id={id}
tabIndex={-1}
{...rest}
>
{children}
{id && <HeadingAnchor id={id} title={children} className="opacity-0 group-hover:opacity-100 max-md:hidden" />}
</h2>
),
h3: ({ className, id, children, ...rest }) => (
<h3
className={cn(
"group mt-6 mb-4 scroll-mt-4 text-lg leading-relaxed font-semibold md:text-xl [&_code]:text-[0.9em] [&_strong]:font-bold [&+*]:mt-0",
className
)}
id={id}
tabIndex={-1}
{...rest}
>
{children}
{id && <HeadingAnchor id={id} title={children} className="opacity-0 group-hover:opacity-100 max-md:hidden" />}
</h3>
),
h4: ({ className, ...rest }) => (
<h4
className={cn(
"mt-6 mb-2 scroll-mt-4 text-base leading-normal font-semibold [&_strong]:font-bold [&+*]:mt-0",
className
)}
{...rest}
/>
),
h5: ({ className, ...rest }) => (
<h5 className={cn("mt-6 mb-2 scroll-mt-4 text-base leading-normal font-medium", className)} {...rest} />
),
h6: ({ className, ...rest }) => (
<h6 className={cn("mt-6 mb-2 scroll-mt-4 text-sm leading-normal font-normal", className)} {...rest} />
),
ul: ({ className, ...rest }) => <ul className={cn("my-5 list-disc pl-7 [&>li]:pl-1.5", className)} {...rest} />,
ol: ({ className, ...rest }) => <ol className={cn("my-5 list-decimal pl-7 [&>li]:pl-1.5", className)} {...rest} />,
li: ({ className, ...rest }) => (
<li
className={cn(
"[&::marker]:text-muted-foreground my-0.5 [&::marker]:font-normal [&>ol]:my-1 [&>ul]:my-1",
className
)}
{...rest}
/>
),
hr: ({ className, ...rest }) => (
<hr className={cn("mx-auto my-6 w-11/12 border-t-2 [&+*]:mt-0", className)} {...rest} />
),
// react components and embeds:
Video,
ImageDiff,
Tweet,
YouTube,
Gist,
CodePen,
};
};