-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathMarkdownProvider.tsx
111 lines (96 loc) · 3.04 KB
/
MarkdownProvider.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
108
109
110
111
import React, { FC } from 'react';
import { useStaticQuery, graphql } from 'gatsby';
import { MDXProvider } from '@mdx-js/react';
import Link from 'src/components/Link';
import { CodeBlock } from './CodeBlock';
const H1: FC<JSX.IntrinsicElements['h1']> = ({ children, ...props }) => (
<h1 className="ui-text-h1 my-40" {...props}>
{children}
</h1>
);
const H2: FC<JSX.IntrinsicElements['h2']> = ({ children, ...props }) => (
<h2 className="ui-text-h2 my-32" {...props}>
{children}
</h2>
);
const H3: FC<JSX.IntrinsicElements['h3']> = ({ children, ...props }) => (
<h3 className="ui-text-h3 my-20" {...props}>
{children}
</h3>
);
const Paragraph: FC<JSX.IntrinsicElements['p']> = ({ children, ...props }) => (
<p className="ui-text-p2 mb-20" {...props}>
{children}
</p>
);
export const Anchor: FC<JSX.IntrinsicElements['a']> = ({ children, href, ...props }) => {
/**
* Inspired by https://github.com/gatsbyjs/gatsby/issues/21462#issuecomment-605606702
* to work around the issues with broken links being emitted by gatsby-plugin-mdx when
* specifying an assetPrefix (like we do in production). So what we do is we "break"
* the asset prefix pretty much like gatsby-plugin-mdx does [1], and if we find the
* broken prefix on the URL we strip it off again...
*
* 1. https://github.com/gatsbyjs/gatsby/blob/3d4d6a6e222cf3bff3f2c2cdfb0cc539bad2403a/packages/gatsby-plugin-mdx/src/remark-path-prefix-plugin.ts#L18-L28
*/
const { site } = useStaticQuery(graphql`
{
site {
assetPrefix
}
}
`);
let cleanHref = href;
const assetPrefix = site.assetPrefix ?? '';
const brokenAssetPrefix = assetPrefix.replace('://', ':/');
if (href?.startsWith(brokenAssetPrefix)) {
cleanHref = href.slice(brokenAssetPrefix.length);
}
return (
<Link to={cleanHref ?? '#'} className="ui-link" {...props}>
{children}
</Link>
);
};
const Ul: FC<JSX.IntrinsicElements['ul']> = ({ children, ...props }) => (
<ul className="ui-unordered-list" {...props}>
{children}
</ul>
);
const Li: FC<JSX.IntrinsicElements['li']> = ({ children, ...props }) => (
<li className="ui-text-p2 mb-8" {...props}>
{children}
</li>
);
const Code: FC<JSX.IntrinsicElements['code']> = ({ children, ...props }) => (
<code className="ui-text-code-inline" {...props}>
{children}
</code>
);
const Pre: FC<JSX.IntrinsicElements['pre']> = ({ children }) => {
const lang = (children as React.ReactElement)?.props?.className?.replace('language-', '');
return (
<div className="mb-20">
<CodeBlock language={lang || 'javascript'}>{children}</CodeBlock>
</div>
);
};
const defaultComponents = {
h1: H1,
h2: H2,
h3: H3,
p: Paragraph,
a: Anchor,
ul: Ul,
li: Li,
code: Code,
pre: Pre,
};
export const MarkdownProvider = ({
children,
components,
}: {
children: React.ReactNode;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
components: Record<string, React.FC<any>>;
}) => <MDXProvider components={{ ...defaultComponents, ...components }}>{children}</MDXProvider>;