-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
mdx-components.tsx
107 lines (104 loc) · 3.12 KB
/
mdx-components.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, { ComponentPropsWithoutRef } from 'react';
import { Link } from 'next-view-transitions';
import type { MDXComponents } from 'mdx/types';
import { highlight } from 'sugar-high';
type HeadingProps = ComponentPropsWithoutRef<'h1'>;
type ParagraphProps = ComponentPropsWithoutRef<'p'>;
type ListProps = ComponentPropsWithoutRef<'ul'>;
type ListItemProps = ComponentPropsWithoutRef<'li'>;
type AnchorProps = ComponentPropsWithoutRef<'a'>;
type BlockquoteProps = ComponentPropsWithoutRef<'blockquote'>;
const components: MDXComponents = {
h1: (props: HeadingProps) => (
<h1 className="font-medium pt-12 mb-0 fade-in" {...props} />
),
h2: (props: HeadingProps) => (
<h2 className="text-gray-800 font-medium mt-8 mb-3" {...props} />
),
h3: (props: HeadingProps) => (
<h3 className="text-gray-800 font-medium mt-8 mb-3" {...props} />
),
h4: (props: HeadingProps) => <h4 className="font-medium" {...props} />,
p: (props: ParagraphProps) => (
<p className="text-gray-800 leading-snug" {...props} />
),
ol: (props: ListProps) => (
<ol className="text-gray-800 list-decimal pl-5 space-y-2" {...props} />
),
ul: (props: ListProps) => (
<ul className="text-gray-800 list-disc pl-5 space-y-1" {...props} />
),
li: (props: ListItemProps) => <li className="pl-1" {...props} />,
em: (props: ComponentPropsWithoutRef<'em'>) => (
<em className="font-medium" {...props} />
),
strong: (props: ComponentPropsWithoutRef<'strong'>) => (
<strong className="font-medium" {...props} />
),
a: ({ href, children, ...props }: AnchorProps) => {
const className = 'text-blue-500 hover:text-blue-700';
if (href?.startsWith('/')) {
return (
<Link href={href} className={className} {...props}>
{children}
</Link>
);
}
if (href?.startsWith('#')) {
return (
<a href={href} className={className} {...props}>
{children}
</a>
);
}
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className={className}
{...props}
>
{children}
</a>
);
},
code: ({ children, ...props }: ComponentPropsWithoutRef<'code'>) => {
const codeHTML = highlight(children as string);
return <code dangerouslySetInnerHTML={{ __html: codeHTML }} {...props} />;
},
Table: ({ data }: { data: { headers: string[]; rows: string[][] } }) => (
<table>
<thead>
<tr>
{data.headers.map((header, index) => (
<th key={index}>{header}</th>
))}
</tr>
</thead>
<tbody>
{data.rows.map((row, index) => (
<tr key={index}>
{row.map((cell, cellIndex) => (
<td key={cellIndex}>{cell}</td>
))}
</tr>
))}
</tbody>
</table>
),
blockquote: (props: BlockquoteProps) => (
<blockquote
className="ml-[0.075em] border-l-3 border-gray-300 pl-4 text-gray-700"
{...props}
/>
),
};
export function useMDXComponents(
otherComponents: MDXComponents,
): MDXComponents {
return {
...otherComponents,
...components,
};
}