@modern-js/plugin-docsite 0.0.0-bundle-deps-202110123508

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +342 -0
  2. package/LICENSE +21 -0
  3. package/README.md +30 -0
  4. package/dist/js/modern/build-task.js +29 -0
  5. package/dist/js/modern/features/build.js +17 -0
  6. package/dist/js/modern/features/constant.js +7 -0
  7. package/dist/js/modern/features/dev.js +24 -0
  8. package/dist/js/modern/features/index.js +47 -0
  9. package/dist/js/modern/features/utils/chokidar.js +37 -0
  10. package/dist/js/modern/features/utils/generate-files.js +197 -0
  11. package/dist/js/modern/features/utils/valid.js +17 -0
  12. package/dist/js/modern/features/utils/webpack.js +63 -0
  13. package/dist/js/modern/index.js +49 -0
  14. package/dist/js/node/build-task.js +33 -0
  15. package/dist/js/node/features/build.js +31 -0
  16. package/dist/js/node/features/constant.js +21 -0
  17. package/dist/js/node/features/dev.js +39 -0
  18. package/dist/js/node/features/index.js +68 -0
  19. package/dist/js/node/features/utils/chokidar.js +55 -0
  20. package/dist/js/node/features/utils/generate-files.js +223 -0
  21. package/dist/js/node/features/utils/valid.js +36 -0
  22. package/dist/js/node/features/utils/webpack.js +80 -0
  23. package/dist/js/node/index.js +61 -0
  24. package/dist/js/static/DocsNav.jsx.tpl +42 -0
  25. package/dist/js/static/DocsRoutes.jsx.tpl +19 -0
  26. package/dist/js/static/DocsToc.jsx.tpl +20 -0
  27. package/dist/js/static/docs-entry.jsx.tpl +41 -0
  28. package/dist/js/static/docs-page.jsx.tpl +107 -0
  29. package/dist/js/static/docs.css +1008 -0
  30. package/dist/js/static/index.html.ejs +15 -0
  31. package/dist/js/static/stories-entry.ts.tpl +6 -0
  32. package/dist/js/static/storybook-config.js.tpl +32 -0
  33. package/dist/js/static/tsconfig.json +25 -0
  34. package/dist/types/build-task.d.ts +1 -0
  35. package/dist/types/features/build.d.ts +5 -0
  36. package/dist/types/features/constant.d.ts +3 -0
  37. package/dist/types/features/dev.d.ts +2 -0
  38. package/dist/types/features/index.d.ts +13 -0
  39. package/dist/types/features/utils/chokidar.d.ts +1 -0
  40. package/dist/types/features/utils/generate-files.d.ts +4 -0
  41. package/dist/types/features/utils/valid.d.ts +9 -0
  42. package/dist/types/features/utils/webpack.d.ts +3 -0
  43. package/dist/types/index.d.ts +15 -0
  44. package/modern.config.js +2 -0
  45. package/package.json +98 -0
  46. package/src/build-task.ts +31 -0
  47. package/src/features/build.ts +31 -0
  48. package/src/features/constant.ts +8 -0
  49. package/src/features/dev.ts +37 -0
  50. package/src/features/index.ts +68 -0
  51. package/src/features/utils/chokidar.ts +44 -0
  52. package/src/features/utils/generate-files.ts +238 -0
  53. package/src/features/utils/valid.ts +23 -0
  54. package/src/features/utils/webpack.ts +107 -0
  55. package/src/index.ts +42 -0
  56. package/src/type.d.ts +4 -0
  57. package/static/DocsNav.jsx.tpl +42 -0
  58. package/static/DocsRoutes.jsx.tpl +19 -0
  59. package/static/DocsToc.jsx.tpl +20 -0
  60. package/static/docs-entry.jsx.tpl +41 -0
  61. package/static/docs-page.jsx.tpl +107 -0
  62. package/static/docs.css +1008 -0
  63. package/static/index.html.ejs +15 -0
  64. package/static/stories-entry.ts.tpl +6 -0
  65. package/static/storybook-config.js.tpl +32 -0
  66. package/static/tsconfig.json +25 -0
  67. package/tsconfig.json +13 -0
@@ -0,0 +1,238 @@
1
+ import path from 'path';
2
+ import { logger, fs } from '@modern-js/utils';
3
+ import matter from 'gray-matter';
4
+ import { startCase, camelCase, union, template, difference } from 'lodash';
5
+ import GithubSlugger from 'github-slugger';
6
+ import sortPaths from 'sort-paths';
7
+ import visit from 'unist-util-visit';
8
+ import toString from 'mdast-util-to-string';
9
+ import u from 'unist-builder';
10
+ import mdx from '@mdx-js/mdx';
11
+ import babelParser, { ParserOptions } from '@modern-js/deps/compiled/babel/parser';
12
+ import {
13
+ DOCS_RENDER_PATH,
14
+ MDX_DEFAULT_RENDERER,
15
+ UTILS_STATIC,
16
+ } from '../constant';
17
+
18
+ const loadTemplate = async (file: string, customPath = false) => {
19
+ let result = '';
20
+ if (customPath) {
21
+ result = await fs.readFile(file, 'utf-8');
22
+ } else {
23
+ result = await fs.readFile(path.join(UTILS_STATIC, file), 'utf-8');
24
+ }
25
+
26
+ return template(result, { interpolate: /<%=([\s\S]+?)%>/g });
27
+ };
28
+
29
+ interface Node {
30
+ value?: string;
31
+ type: string;
32
+ depth?: number;
33
+ url?: string;
34
+ data?: {
35
+ hProperties: {
36
+ id: string;
37
+ };
38
+ };
39
+ children?: Node[];
40
+ }
41
+
42
+ // eslint-disable-next-line max-statements
43
+ async function handleFile(
44
+ appDirectory: string,
45
+ tmpDir: string,
46
+ file: string,
47
+ images: string[],
48
+ ) {
49
+ const moduleName = file.replace(/\.(md|mdx)$/, '');
50
+ const content = await fs.readFile(path.resolve(appDirectory, 'docs', file));
51
+ const parsed = matter(content);
52
+ if (!parsed.data.title) {
53
+ parsed.data.title = startCase(camelCase(path.basename(moduleName)));
54
+ }
55
+
56
+ const slugger = new GithubSlugger();
57
+ slugger.reset();
58
+
59
+ const babelOptions: ParserOptions = {
60
+ allowUndeclaredExports: true,
61
+ sourceType: 'module',
62
+ };
63
+ const imported: { id: string; node: any }[] = [];
64
+ const exported: { id: string; node: any }[] = [];
65
+ const toc: { slug: string; text: string }[] = [];
66
+
67
+ const modifier = () => (tree: any) => {
68
+ visit<Node>(tree, 'import', node => {
69
+ const parsedNode = babelParser.parse(node.value!, babelOptions);
70
+ const nodes = parsedNode.program.body;
71
+ nodes.forEach((n: any) => {
72
+ if (n.type === 'ImportDeclaration') {
73
+ n.specifiers.forEach((sp: any) => {
74
+ imported.push({
75
+ id: sp.local.name,
76
+ node,
77
+ });
78
+ });
79
+ }
80
+ });
81
+ });
82
+ visit<Node>(tree, 'export', node => {
83
+ const parsedNode = babelParser.parse(node.value!, babelOptions);
84
+ const nodes = parsedNode.program.body;
85
+ nodes.forEach((n: any) => {
86
+ if (n.type === 'ExportNamedDeclaration') {
87
+ n.specifiers.forEach((sp: any) => {
88
+ exported.push({
89
+ id: sp.exported.name,
90
+ node,
91
+ });
92
+ });
93
+ }
94
+ });
95
+ });
96
+ const extraImported = difference(
97
+ imported.map(n => n.id),
98
+ exported.map(n => n.id),
99
+ );
100
+ // we have to put the export statement with the import,
101
+ // otherwise the mdx's babel transformer cannot found
102
+ // the corresponding imports
103
+ extraImported.forEach(id => {
104
+ const { node } = imported.find(n => n.id === id)!;
105
+ node.value += `\nexport { ${id} };`;
106
+ });
107
+ visit<Node>(tree, 'heading', node => {
108
+ if (node.depth === 2) {
109
+ const slug = slugger.slug(toString(node));
110
+ node.data = { hProperties: { id: slug } };
111
+ toc.push({
112
+ slug,
113
+ text: toString(node),
114
+ });
115
+ }
116
+ });
117
+ visit<Node>(tree, 'root', node => {
118
+ (node.children || []).unshift(
119
+ u('heading', {
120
+ depth: 1,
121
+ children: [u('text', { value: parsed.data.title })],
122
+ }),
123
+ );
124
+ });
125
+ visit<Node>(tree, 'image', node => {
126
+ const { url } = node;
127
+ if (!url!.startsWith('http')) {
128
+ const fullPath = path.resolve(
129
+ path.dirname(path.resolve(appDirectory, 'docs', file)),
130
+ url!,
131
+ );
132
+ const relativePath = path.relative(
133
+ path.resolve(appDirectory, 'assets'),
134
+ fullPath,
135
+ );
136
+ if (relativePath.startsWith('..')) {
137
+ logger.warn(
138
+ `${url!} referenced in ${file} is not under the "assets" folder`,
139
+ );
140
+ } else {
141
+ images.push(relativePath);
142
+ node.url = `/${path.relative(
143
+ path.dirname(path.resolve(appDirectory, 'docs', file)),
144
+ path.resolve(appDirectory, 'docs/assets', relativePath),
145
+ )}`;
146
+ }
147
+ }
148
+ });
149
+ };
150
+
151
+ const transpiled = await mdx(parsed.content, { remarkPlugins: [modifier] });
152
+ const totalExported = union(
153
+ imported.map(n => n.id),
154
+ exported.map(n => n.id),
155
+ );
156
+ const outputFile = path.resolve(tmpDir, `${moduleName}/mdx.jsx`);
157
+ await fs.outputFile(outputFile, MDX_DEFAULT_RENDERER + transpiled, {
158
+ encoding: 'utf8',
159
+ });
160
+
161
+ const pageFile = path.resolve(tmpDir, `${moduleName}/index.jsx`);
162
+ const pageTemplate = await loadTemplate('docs-page.jsx.tpl');
163
+ const pageContent = pageTemplate({
164
+ moduleName,
165
+ toc: JSON.stringify(toc),
166
+ relRoot: path.relative(path.dirname(outputFile), tmpDir),
167
+ imports: totalExported.length
168
+ ? `import { ${totalExported.join(', ')} } from './mdx';`
169
+ : '',
170
+ imported: totalExported.join(','),
171
+ });
172
+ await fs.outputFile(pageFile, pageContent, { encoding: 'utf8' });
173
+ return {
174
+ ...parsed.data,
175
+ moduleName,
176
+ pageFile,
177
+ };
178
+ }
179
+ export async function generateFiles(
180
+ appDirectory: string,
181
+ tmpDir: string,
182
+ files: string[],
183
+ isDev: boolean,
184
+ ) {
185
+ await fs.remove(tmpDir);
186
+ await fs.ensureDir(tmpDir);
187
+ const images: string[] = [];
188
+
189
+ const meta = await Promise.all(
190
+ files.map(file => handleFile(appDirectory, tmpDir, file, images)),
191
+ );
192
+ const sorted: { moduleName: string; title: string }[] = sortPaths(
193
+ meta,
194
+ (e: { moduleName: string; title: string }) =>
195
+ e.moduleName.endsWith('index')
196
+ ? e.moduleName.replace(/index$/, '')
197
+ : `${e.moduleName}/`,
198
+ '/',
199
+ );
200
+ const routesTemplate = await loadTemplate('DocsRoutes.jsx.tpl');
201
+ await fs.outputFile(
202
+ path.resolve(tmpDir, 'DocsRoutes.jsx'),
203
+ routesTemplate({ meta: sorted }),
204
+ );
205
+ const pkgInfo = await fs.readJson(path.resolve(appDirectory, 'package.json'));
206
+ const entryTemplate = await loadTemplate('docs-entry.jsx.tpl');
207
+ await fs.outputFile(
208
+ path.resolve(tmpDir, 'docs-entry.jsx'),
209
+ entryTemplate({
210
+ basename: isDev
211
+ ? '/'
212
+ : `${DOCS_RENDER_PATH}/${pkgInfo.name}/${pkgInfo.version}`,
213
+ }),
214
+ );
215
+ await Promise.all(
216
+ ['DocsNav.jsx.tpl', 'DocsToc.jsx.tpl', 'docs.css'].map(async file =>
217
+ fs.copyFile(
218
+ path.resolve(UTILS_STATIC, file),
219
+ path.resolve(tmpDir, file.replace('.tpl', '')),
220
+ ),
221
+ ),
222
+ );
223
+ await fs.outputJson(
224
+ path.resolve(tmpDir, 'meta.json'),
225
+ sorted.map(({ title, moduleName }) => ({ title, moduleName })),
226
+ { spaces: 2 },
227
+ );
228
+ await fs.ensureDir(path.resolve(appDirectory, 'dist/docs/assets'));
229
+ await Promise.all(
230
+ Array.from(new Set(images)).map(file =>
231
+ fs.copyFile(
232
+ path.resolve(appDirectory, 'assets', file),
233
+ path.resolve(appDirectory, 'dist/docs/assets', file),
234
+ ),
235
+ ),
236
+ );
237
+ return sorted;
238
+ }
@@ -0,0 +1,23 @@
1
+ import path from 'path';
2
+ import * as glob from 'glob';
3
+ import { chalk, fs } from '@modern-js/utils';
4
+
5
+ interface ValidOption {
6
+ appDirectory: string;
7
+ docsDir: string;
8
+ }
9
+
10
+ export const valid = ({ appDirectory, docsDir }: ValidOption) => {
11
+ const docsAbsPath = path.join(appDirectory, docsDir);
12
+ const files: string[] = glob.sync(`${docsAbsPath}/**/*.{md,mdx}`);
13
+ if (!fs.existsSync(docsAbsPath) || files.length <= 0) {
14
+ console.info(
15
+ chalk.yellow(
16
+ 'No docs found, create directory "./docs" and add md(x) files',
17
+ ),
18
+ );
19
+ return false;
20
+ }
21
+
22
+ return true;
23
+ };
@@ -0,0 +1,107 @@
1
+ import path from 'path';
2
+ import { fs } from '@modern-js/utils';
3
+ import HtmlWebpackPlugin from '@modern-js/deps/compiled/html-webpack-plugin';
4
+ import webpack, {
5
+ Configuration,
6
+ WebpackPluginInstance,
7
+ } from '@modern-js/deps/compiled/webpack';
8
+ import { getWebpackConfig, WebpackConfigTarget } from '@modern-js/webpack';
9
+ import { UTILS_STATIC } from '../constant';
10
+
11
+ interface Alias {
12
+ [index: string]: string | false | string[];
13
+ }
14
+
15
+ export function generatorWebpackConfig(
16
+ appDirectory: string,
17
+ tmpDir: string,
18
+ isDev: boolean,
19
+ ): Configuration {
20
+ const originConfig: any = getWebpackConfig(WebpackConfigTarget.CLIENT);
21
+ const plugins = (
22
+ (originConfig.plugins || []) as WebpackPluginInstance[]
23
+ ).filter(p => p.constructor !== webpack.HotModuleReplacementPlugin);
24
+ const config: Configuration = {
25
+ mode: isDev ? 'development' : 'production',
26
+ context: tmpDir,
27
+ entry: { index: path.resolve(tmpDir, 'docs-entry.jsx') },
28
+ output: { path: path.resolve(appDirectory, 'dist/docs') },
29
+ resolve: originConfig.resolve || { alias: {} },
30
+ module: originConfig.module,
31
+ plugins: [
32
+ ...plugins,
33
+ new HtmlWebpackPlugin({
34
+ templateContent: fs.readFileSync(
35
+ path.resolve(UTILS_STATIC, 'index.html.ejs'),
36
+ 'utf8',
37
+ ),
38
+ }),
39
+ ],
40
+ };
41
+
42
+ config.resolve!.modules = [
43
+ ...(config.resolve!.modules || []),
44
+ path.join(__dirname, '../../../../../', 'node_modules'),
45
+ ];
46
+ (config.resolve!.alias as Alias)['@assets'] = path.resolve(
47
+ appDirectory,
48
+ 'assets',
49
+ );
50
+ (config.resolve!.alias as Alias)['@styles'] = path.resolve(
51
+ appDirectory,
52
+ 'styles',
53
+ );
54
+ // fix this since react-live relies on core-js@2
55
+ (config.resolve!.alias as Alias)[
56
+ `${path.dirname(require.resolve('core-js'))}/fn`
57
+ ] = 'core-js/es';
58
+
59
+ const pkgJSON = JSON.parse(
60
+ fs.readFileSync(path.join(appDirectory, 'package.json'), 'utf-8'),
61
+ );
62
+
63
+ if (pkgJSON.dependencies.react || pkgJSON.devDependencies.react) {
64
+ (config.resolve!.alias as Alias).react = path.resolve('node_modules/react');
65
+ } else {
66
+ (config.resolve!.alias as Alias).react = path.resolve(
67
+ __dirname,
68
+ '../../../../../',
69
+ 'node_modules',
70
+ 'react',
71
+ );
72
+ }
73
+ if (
74
+ pkgJSON.dependencies['react-dom'] ||
75
+ pkgJSON.devDependencies['react-dom']
76
+ ) {
77
+ (config.resolve!.alias as Alias)['react-dom'] = path.resolve(
78
+ 'node_modules/react-dom',
79
+ );
80
+ } else {
81
+ (config.resolve!.alias as Alias)['react-dom'] = path.resolve(
82
+ __dirname,
83
+ '../../../../../',
84
+ 'node_modules',
85
+ 'react-dom',
86
+ );
87
+ }
88
+
89
+ config.resolve!.fallback = {
90
+ path: require.resolve('path-browserify'),
91
+ };
92
+ return config;
93
+ }
94
+
95
+ export async function runWebpack(config: Configuration) {
96
+ await new Promise((resolve, reject) => {
97
+ webpack(config).run((err, stats) => {
98
+ if (err) {
99
+ reject(err);
100
+ } else if (stats?.hasErrors()) {
101
+ reject(stats?.compilation.errors);
102
+ } else {
103
+ resolve(stats);
104
+ }
105
+ });
106
+ });
107
+ }
package/src/index.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { Import } from '@modern-js/utils';
2
+
3
+ const core: typeof import('@modern-js/core') = Import.lazy(
4
+ '@modern-js/core',
5
+ require,
6
+ );
7
+ const features: typeof import('./features') = Import.lazy(
8
+ './features',
9
+ require,
10
+ );
11
+
12
+ export default core.createPlugin(
13
+ () => ({
14
+ commands({ program }: any) {
15
+ const { appDirectory } = core.useAppContext();
16
+ const devCommand = program.commandsMap.get('dev');
17
+ if (devCommand) {
18
+ devCommand.command('docs').action(async () => {
19
+ await features.buildDocs({ appDirectory, isDev: true });
20
+ });
21
+ }
22
+ },
23
+ // module-tools menu mode
24
+ moduleToolsMenu() {
25
+ const { appDirectory } = core.useAppContext();
26
+ return {
27
+ name: 'Docsite 调试',
28
+ value: 'docsite',
29
+ runTask: async () => features.buildDocs({ appDirectory, isDev: true }),
30
+ };
31
+ },
32
+ platformBuild() {
33
+ return {
34
+ name: 'docsite',
35
+ title: 'Run Docsite log',
36
+ taskPath: require.resolve('./build-task'),
37
+ params: [],
38
+ };
39
+ },
40
+ }),
41
+ { name: '@modern-js/plugin-docsite' },
42
+ );
package/src/type.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ /// <reference types="@modern-js/module-tools-hooks" />
2
+ declare module 'find-node-modules';
3
+ declare module '@mdx-js/mdx';
4
+ declare module 'sort-paths';
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Link } from 'react-router-dom';
4
+ import Menu from 'antd/es/menu';
5
+
6
+ const MenuItem = Menu.Item;
7
+ const { SubMenu } = Menu;
8
+
9
+ const Container = styled.div`
10
+ position: relative;
11
+ box-sizing: border-box;
12
+ height: 100%;
13
+ padding: 2rem 0;
14
+ border-right: 1px solid var(--theme-border);
15
+ overflow: auto;
16
+ `;
17
+
18
+ const DocsNav = ({ meta }) => {
19
+ return (
20
+ <Container>
21
+ <Menu>
22
+ {meta.map(page => {
23
+ const parts = page.moduleName.split(/\//g) || [];
24
+ if (parts[parts.length - 1] === 'index') {
25
+ parts.pop();
26
+ }
27
+ const level = Math.max(parts.length, 1);
28
+
29
+ return (
30
+ <MenuItem
31
+ key={page.moduleName}
32
+ style={{ paddingLeft: `${level + 0.5}rem` }}>
33
+ <Link to={`/${page.moduleName}`}>{page.title}</Link>
34
+ </MenuItem>
35
+ );
36
+ })}
37
+ </Menu>
38
+ </Container>
39
+ );
40
+ };
41
+
42
+ export default DocsNav;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import {
3
+ Switch,
4
+ Route,
5
+ Redirect,
6
+ } from "react-router-dom";
7
+
8
+ const DocsRoutes = ({ meta }) => {
9
+ return (
10
+ <Switch>
11
+ <Redirect exact from='/' to="/<%= meta[0].moduleName %>" />
12
+ <% meta.forEach(function(page) { %>
13
+ <Route path={'/<%= page.moduleName %>'} component={require('./<%= page.moduleName %>/index').default}/>
14
+ <% }); %>
15
+ </Switch>
16
+ );
17
+ };
18
+
19
+ export default DocsRoutes;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import Anchor from 'antd/es/anchor';
4
+
5
+ const AnchorLink = Anchor.Link;
6
+
7
+ const DocsToc = ({ entries }) => {
8
+ return (
9
+ <Anchor affix={false} scrollContainer=".markdown-body">
10
+ {entries.map(entry => (
11
+ <AnchorLink
12
+ key={entry.slug}
13
+ href={`#${entry.slug}`}
14
+ title={entry.text}
15
+ />
16
+ ))}
17
+ </Anchor>
18
+ );
19
+ };
20
+ export default DocsToc;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { render } from 'react-dom';
3
+ import styled from 'styled-components';
4
+ import { BrowserRouter as Router } from 'react-router-dom';
5
+ import DocsNav from './DocsNav';
6
+ import DocsRoutes from './DocsRoutes';
7
+ import meta from './meta.json';
8
+ import 'antd/dist/antd.css';
9
+ import './docs.css';
10
+
11
+ const NavWrapper = styled.div`
12
+ position: absolute;
13
+ top: 0;
14
+ bottom: 0;
15
+ left: 0;
16
+ width: 12rem;
17
+ overflow-y: auto;
18
+ `;
19
+ const MainWrapper = styled.div`
20
+ position: absolute;
21
+ top: 0;
22
+ bottom: 0;
23
+ left: 12rem;
24
+ right: 0;
25
+ `;
26
+
27
+ const App = () => (
28
+ <Router basename="<%= basename || '/' %>">
29
+ <NavWrapper>
30
+ <DocsNav meta={meta} />
31
+ </NavWrapper>
32
+ <MainWrapper>
33
+ <DocsRoutes />
34
+ </MainWrapper>
35
+ </Router>
36
+ );
37
+
38
+ const root = document.createElement('div');
39
+ root.setAttribute('id', 'root');
40
+ document.body.append(root);
41
+ render(<App />, document.querySelector('#root'));
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import { MDXProvider, mdx } from '@mdx-js/react';
3
+ import Highlight, { defaultProps } from 'prism-react-renderer';
4
+ import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live';
5
+ import styled from 'styled-components';
6
+ import DocsNav from './<%= relRoot %>/DocsNav';
7
+ import DocsToc from './<%= relRoot %>/DocsToc';
8
+ import Main from './mdx';
9
+ <%= imports %>
10
+
11
+ const CodeBlock = ({ children, className, live, render }) => {
12
+ const language = className.replace(/language-/, '');
13
+ if (live) {
14
+ return (
15
+ <div style={{ marginTop: '40px' }}>
16
+ <LiveProvider
17
+ code={children.trim()}
18
+ transformCode={code => `/** @jsx mdx */${code}`}
19
+ scope={{
20
+ mdx,
21
+ <%= imported %>
22
+ }}>
23
+ <LivePreview style={{
24
+ boxShadow: '0 0 10px 5px gray',
25
+ margin: '1rem 0',
26
+ padding: '1rem',
27
+ }}/>
28
+ <LiveError />
29
+ <LiveEditor style={{ backgroundColor: 'black', color: 'white' }} />
30
+ </LiveProvider>
31
+ </div>
32
+ );
33
+ }
34
+ if (render) {
35
+ return (
36
+ <div style={{ marginTop: '40px' }}>
37
+ <LiveProvider code={children.trim()}
38
+ transformCode={code => `/** @jsx mdx */${code}`}
39
+ scope={{
40
+ mdx,
41
+ <%= imported %>
42
+ }}>
43
+ <LivePreview style={{
44
+ boxShadow: '0 0 10px 5px gray',
45
+ margin: '1rem 0',
46
+ padding: '1rem',
47
+ }}/>
48
+ </LiveProvider>
49
+ </div>
50
+ );
51
+ }
52
+
53
+ return (
54
+ <Highlight {...defaultProps} code={children.trim()} language={language}>
55
+ {({ className, style, tokens, getLineProps, getTokenProps }) => (
56
+ <pre className={className} style={{ ...style, padding: '20px' }}>
57
+ {tokens.map((line, i) => (
58
+ <div key={i} {...getLineProps({ line, key: i })}>
59
+ {line.map((token, key) => (
60
+ <span key={key} {...getTokenProps({ token, key })} />
61
+ ))}
62
+ </div>
63
+ ))}
64
+ </pre>
65
+ )}
66
+ </Highlight>
67
+ );
68
+ };
69
+
70
+ const components = {
71
+ pre: props => <div {...props} />,
72
+ code: CodeBlock,
73
+ <%= imported %>
74
+ };
75
+
76
+ const Wrapper = styled.div`
77
+ height: 100%;
78
+ display: flex;
79
+ flex-direction: row;
80
+ `;
81
+ const MainWrapper = styled.div`
82
+ flex: 1;
83
+ overflow-y: scroll;
84
+ padding-right: 230px !important;
85
+ `;
86
+ const TocWrapper = styled.div`
87
+ position: fixed;
88
+ top: 2rem;
89
+ right: 1.5rem;
90
+ `;
91
+
92
+ const Page = () => {
93
+ return (
94
+ <Wrapper>
95
+ <MainWrapper className="markdown-body">
96
+ <MDXProvider components={components}>
97
+ <Main />
98
+ </MDXProvider>
99
+ </MainWrapper>
100
+ <TocWrapper>
101
+ <DocsToc entries={JSON.parse('<%= toc %>')}/>
102
+ </TocWrapper>
103
+ </Wrapper>
104
+ );
105
+ };
106
+
107
+ export default Page;