-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmdx-components.tsx
More file actions
112 lines (97 loc) · 2.24 KB
/
mdx-components.tsx
File metadata and controls
112 lines (97 loc) · 2.24 KB
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
108
109
110
111
112
import type { MDXComponents } from 'mdx/types'
import Link from 'next/link'
import Image, { type ImageProps } from 'next/image'
import { highlight } from 'sugar-high'
import slugify from 'slugify'
import React from 'react'
type TableProps = {
data: {
headers: string[]
rows: string[][]
}
}
function Table({ data }: TableProps) {
const headers = data.headers.map((header, index) => (
<th key={index}>{header}</th>
))
const rows = data.rows.map((row, index) => (
<tr key={index}>
{row.map((cell, cellIndex) => (
<td key={cellIndex}>{cell}</td>
))}
</tr>
))
return (
<table>
<thead>
<tr>{headers}</tr>
</thead>
<tbody>{rows}</tbody>
</table>
)
}
type CustomLinkProps = {
href: string
children: React.ReactNode
}
function CustomLink(props: CustomLinkProps) {
const href = props.href
if (href.startsWith('/')) {
return (
<Link {...props}>
{props.children}
</Link>
)
}
if (href.startsWith('#')) {
return <a {...props} />
}
return <a target="_blank" rel="noopener noreferrer" {...props} />
}
function RoundedImage({ alt, ...props}: ImageProps) {
return <Image alt={alt} className="rounded-lg" {...props} />
}
type CodeProps = {
children: string
}
function Code({ children, ...props }: CodeProps) {
const codeHTML = highlight(children)
return <code dangerouslySetInnerHTML={{ __html: codeHTML }} {...props} />
}
function createHeading(level: number) {
const Heading = ({ children }: { children: string }) => {
const slug = slugify(children)
return React.createElement(
`h${level}`,
{ id: slug },
[
React.createElement('a', {
href: `#${slug}`,
key: `link-${slug}`,
className: 'anchor',
}),
],
children
)
}
Heading.displayName = `Heading${level}`
return Heading
}
const mdxComponents: MDXComponents = {
h1: createHeading(1),
h2: createHeading(2),
h3: createHeading(3),
h4: createHeading(4),
h5: createHeading(5),
h6: createHeading(6),
Image: RoundedImage,
a: CustomLink,
code: Code,
Table,
}
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...mdxComponents,
...components,
}
}