vite-plugin-react-deck 1.0.0
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.
- package/codegen.d.ts +1 -0
- package/helpers.d.ts +6 -0
- package/index.cjs +296 -0
- package/index.d.ts +4 -0
- package/index.mjs +272 -0
- package/package.json +30 -0
- package/slides.d.ts +35 -0
- package/types.d.ts +3 -0
package/codegen.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function extractMainCodeAsChildren(source: string): string;
|
package/helpers.d.ts
ADDED
package/index.cjs
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
+
for (let key of __getOwnPropNames(from))
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
11
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
12
|
+
}
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
16
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
17
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
18
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
19
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
20
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
21
|
+
mod
|
|
22
|
+
));
|
|
23
|
+
|
|
24
|
+
// src/index.ts
|
|
25
|
+
var fs = __toESM(require("fs/promises"), 1);
|
|
26
|
+
|
|
27
|
+
// src/slides.ts
|
|
28
|
+
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
29
|
+
var import_mdx = require("@mdx-js/mdx");
|
|
30
|
+
|
|
31
|
+
// src/codegen.ts
|
|
32
|
+
function extractMainCodeAsChildren(source) {
|
|
33
|
+
const start = source.indexOf("const _components = {");
|
|
34
|
+
const end = source.indexOf("\n}", start);
|
|
35
|
+
const components = source.slice(start, end);
|
|
36
|
+
if (!components) {
|
|
37
|
+
return "";
|
|
38
|
+
}
|
|
39
|
+
const withWrapper = components.replace(
|
|
40
|
+
/};\s*return/gm,
|
|
41
|
+
"};\n const {wrapper: MDXLayout} = _components;\nreturn"
|
|
42
|
+
);
|
|
43
|
+
const hasLayout = withWrapper.match(/\n\s*return (<>|_jsxs\(_Fragment)/gm);
|
|
44
|
+
if (hasLayout) {
|
|
45
|
+
return withWrapper.replace(/\n\s*return <>/gm, "\nreturn <MDXLayout {...props}>").replace(/<\/>;\s*$/gm, "</MDXLayout>;\n").replace(
|
|
46
|
+
"return _jsxs(_Fragment, {",
|
|
47
|
+
" return _jsx(MDXLayout, {...props,"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const result = withWrapper.replace(/\n\s*return\s*</gm, "\nreturn <MDXLayout {...props}><").replace(/>;\s*$/gm, "></MDXLayout>;\n").replace(
|
|
51
|
+
"return _jsx(_components",
|
|
52
|
+
" return _jsx(MDXLayout, {...props, children: _jsx(_components"
|
|
53
|
+
).replace(/}\);$/gm, "})});");
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/slides.ts
|
|
58
|
+
async function transformSlidesMdxToReact(sourceContent, {
|
|
59
|
+
production: isProd,
|
|
60
|
+
...options
|
|
61
|
+
}) {
|
|
62
|
+
const { data: metadata, content } = (0, import_gray_matter.default)(sourceContent);
|
|
63
|
+
const { content: finalContent, inlineModules } = extractInlineModules(
|
|
64
|
+
normalizeNewline(content)
|
|
65
|
+
);
|
|
66
|
+
const slides = finalContent.split("---");
|
|
67
|
+
const enrichedSlides = [];
|
|
68
|
+
const LAYOUT_REGEX = /\S*\nlayout: (.*)/g;
|
|
69
|
+
let frontmatterForNextSlide = null;
|
|
70
|
+
for (const slide of slides) {
|
|
71
|
+
if (LAYOUT_REGEX.test(slide)) {
|
|
72
|
+
frontmatterForNextSlide = (0, import_gray_matter.default)(`---
|
|
73
|
+
${slide}
|
|
74
|
+
---`).data;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
enrichedSlides.push({
|
|
78
|
+
metadata: frontmatterForNextSlide,
|
|
79
|
+
content: slide
|
|
80
|
+
});
|
|
81
|
+
frontmatterForNextSlide = null;
|
|
82
|
+
}
|
|
83
|
+
const compiledSlides = await Promise.all(
|
|
84
|
+
enrichedSlides.map(async (slide) => {
|
|
85
|
+
const code = addInlineModules(slide.content, inlineModules);
|
|
86
|
+
const normalizedCode = code.replace("process.env", "process\u200B.env");
|
|
87
|
+
const result = await (0, import_mdx.compile)(normalizedCode, {
|
|
88
|
+
outputFormat: "program",
|
|
89
|
+
jsx: !isProd,
|
|
90
|
+
providerImportSource: "@mdx-js/react",
|
|
91
|
+
...options
|
|
92
|
+
});
|
|
93
|
+
const mainCode = extractMainCodeAsChildren(result.value.toString());
|
|
94
|
+
return {
|
|
95
|
+
...slide,
|
|
96
|
+
mdxContent: mainCode
|
|
97
|
+
};
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
return addInlineModules(
|
|
101
|
+
`
|
|
102
|
+
import React from 'react';
|
|
103
|
+
${isProd ? 'import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";import {useMDXComponents as _provideComponents} from "@mdx-js/react" ' : "import {useMDXComponents as _provideComponents} from '@mdx-js/react';"}
|
|
104
|
+
|
|
105
|
+
export default {
|
|
106
|
+
metadata: ${JSON.stringify(metadata)},
|
|
107
|
+
slides: [${compiledSlides.map(
|
|
108
|
+
(slide) => `{
|
|
109
|
+
metadata: ${JSON.stringify(slide.metadata)},
|
|
110
|
+
slideComponent: (baseProps) => {
|
|
111
|
+
const props = {...baseProps, frontmatter: ${JSON.stringify(
|
|
112
|
+
slide.metadata
|
|
113
|
+
)} };
|
|
114
|
+
${slide.mdxContent}
|
|
115
|
+
}
|
|
116
|
+
}`
|
|
117
|
+
).join(",")}
|
|
118
|
+
]
|
|
119
|
+
};`,
|
|
120
|
+
inlineModules
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
var MOD_REG = /\\`|`(?:\\`|[^`])*`|(^(?:import|export).*$)/gm;
|
|
124
|
+
function extractInlineModules(source, {
|
|
125
|
+
inlineModules = /* @__PURE__ */ new Set()
|
|
126
|
+
} = {}) {
|
|
127
|
+
const finalContent = source.replace(MOD_REG, (value, group1) => {
|
|
128
|
+
if (!group1) {
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
inlineModules.add(value);
|
|
132
|
+
return "";
|
|
133
|
+
});
|
|
134
|
+
return { content: finalContent, inlineModules };
|
|
135
|
+
}
|
|
136
|
+
function addInlineModules(source, inlineModules) {
|
|
137
|
+
return `
|
|
138
|
+
${[...inlineModules.keys()].join("\n")}
|
|
139
|
+
|
|
140
|
+
${source}
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
var CRLF = "\r\n";
|
|
144
|
+
function normalizeNewline(input) {
|
|
145
|
+
return input.replace(new RegExp(CRLF, "g"), "\n");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/helpers.ts
|
|
149
|
+
function createIndexFile({ entrypoint }) {
|
|
150
|
+
return `<!DOCTYPE html>
|
|
151
|
+
<html lang="en">
|
|
152
|
+
<head>
|
|
153
|
+
<meta charset="utf-8" />
|
|
154
|
+
<title>Title</title>
|
|
155
|
+
|
|
156
|
+
<style>
|
|
157
|
+
html {
|
|
158
|
+
--code-preview-background-color: #222;
|
|
159
|
+
}
|
|
160
|
+
</style>
|
|
161
|
+
|
|
162
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
163
|
+
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
|
164
|
+
</head>
|
|
165
|
+
<body>
|
|
166
|
+
<div id="root"></div>
|
|
167
|
+
<script type="module" src="${entrypoint}"></script>
|
|
168
|
+
</body>
|
|
169
|
+
</html>
|
|
170
|
+
`;
|
|
171
|
+
}
|
|
172
|
+
function createAppDeckFile({ slidePath }) {
|
|
173
|
+
return `import React, { StrictMode } from "react";
|
|
174
|
+
import * as ReactDOM from "react-dom/client";
|
|
175
|
+
import { Deck } from '@gpichot/spectacle-deck';
|
|
176
|
+
|
|
177
|
+
import deck from "${slidePath}";
|
|
178
|
+
|
|
179
|
+
const root = ReactDOM.createRoot(
|
|
180
|
+
document.getElementById("root") as HTMLElement
|
|
181
|
+
);
|
|
182
|
+
root.render(
|
|
183
|
+
<StrictMode>
|
|
184
|
+
<Deck deck={deck} />
|
|
185
|
+
</StrictMode>
|
|
186
|
+
)`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/index.ts
|
|
190
|
+
var glob = __toESM(require("glob"), 1);
|
|
191
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
192
|
+
async function checkIfDirectoryExists(path2) {
|
|
193
|
+
try {
|
|
194
|
+
await fs.access(path2);
|
|
195
|
+
return true;
|
|
196
|
+
} catch {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
var src_default = (options) => {
|
|
201
|
+
let isProd = false;
|
|
202
|
+
const deckConfig = {
|
|
203
|
+
decks: []
|
|
204
|
+
};
|
|
205
|
+
return {
|
|
206
|
+
name: "react-deck",
|
|
207
|
+
async config(config) {
|
|
208
|
+
var _a, _b, _c;
|
|
209
|
+
const decks = await glob.glob("./src/**/deck.mdx");
|
|
210
|
+
const inputs = ((_b = (_a = config.build) == null ? void 0 : _a.rollupOptions) == null ? void 0 : _b.input) || {};
|
|
211
|
+
deckConfig.decks = decks.map((deck) => ({
|
|
212
|
+
originalFile: deck,
|
|
213
|
+
index: deck.replace("/deck.mdx", "/index.html").replace("src/", "")
|
|
214
|
+
}));
|
|
215
|
+
const newInputs = decks.reduce((acc, deck) => {
|
|
216
|
+
const deckPath = deck.replace("/deck.mdx", "");
|
|
217
|
+
return [...acc, `${deckPath.replace("src/", "")}/index.html`];
|
|
218
|
+
}, []);
|
|
219
|
+
const finalInputs = typeof inputs === "string" ? [inputs, ...decks] : Array.isArray(inputs) ? [...inputs, ...decks] : { ...inputs, ...newInputs };
|
|
220
|
+
return {
|
|
221
|
+
...config,
|
|
222
|
+
build: {
|
|
223
|
+
...config.build,
|
|
224
|
+
rollupOptions: {
|
|
225
|
+
...(_c = config.build) == null ? void 0 : _c.rollupOptions,
|
|
226
|
+
input: finalInputs
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
configResolved(config) {
|
|
232
|
+
isProd = config.isProduction;
|
|
233
|
+
},
|
|
234
|
+
resolveId(id) {
|
|
235
|
+
if (deckConfig.decks.some((deck) => deck.index === id)) {
|
|
236
|
+
return id;
|
|
237
|
+
}
|
|
238
|
+
if (id.endsWith("__deck.tsx")) {
|
|
239
|
+
return id;
|
|
240
|
+
}
|
|
241
|
+
if (id.endsWith("deck.mdx")) {
|
|
242
|
+
return id;
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
async load(id) {
|
|
246
|
+
const deck = deckConfig.decks.find((deck2) => deck2.index === id);
|
|
247
|
+
if (deck) {
|
|
248
|
+
return createIndexFile({
|
|
249
|
+
entrypoint: deck.originalFile.replace("deck.mdx", "__deck.tsx")
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (id.endsWith("__deck.tsx")) {
|
|
253
|
+
const directory = id.replace("/__deck.tsx", "");
|
|
254
|
+
const dir2 = directory.startsWith(".") ? directory : `./${directory}`;
|
|
255
|
+
const path2 = `${dir2}/deck.mdx`;
|
|
256
|
+
if (!await checkIfDirectoryExists(path2)) {
|
|
257
|
+
console.warn(`No deck.mdx file found in ${path2}`);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const contentIndex = createAppDeckFile({
|
|
261
|
+
slidePath: `${directory}/deck.mdx`
|
|
262
|
+
});
|
|
263
|
+
return contentIndex;
|
|
264
|
+
}
|
|
265
|
+
if (!id.endsWith("deck.mdx"))
|
|
266
|
+
return;
|
|
267
|
+
const content = await fs.readFile(id, "utf-8");
|
|
268
|
+
const data = await transformSlidesMdxToReact(content, {
|
|
269
|
+
production: isProd,
|
|
270
|
+
...options
|
|
271
|
+
});
|
|
272
|
+
const dir = import_node_path.default.relative(process.cwd(), id);
|
|
273
|
+
return data;
|
|
274
|
+
},
|
|
275
|
+
transformIndexHtml: {
|
|
276
|
+
order: "pre",
|
|
277
|
+
enforce: "pre",
|
|
278
|
+
transform: async (html, ctx) => {
|
|
279
|
+
var _a;
|
|
280
|
+
const originalUrl = ((_a = ctx.originalUrl) == null ? void 0 : _a.split("?")[0]) || "";
|
|
281
|
+
const deckDir = ctx.path.replace("/index.html", "");
|
|
282
|
+
const dir = originalUrl ? `./src${originalUrl}` : `.${deckDir}`;
|
|
283
|
+
const path2 = `${dir}/deck.mdx`;
|
|
284
|
+
if (!await checkIfDirectoryExists(path2)) {
|
|
285
|
+
return html.replace("__SCRIPT__", `./src/main.tsx`);
|
|
286
|
+
}
|
|
287
|
+
const deckPath = dir.startsWith(".") ? dir : `.${dir}`;
|
|
288
|
+
return html.replace("__SCRIPT__", `${deckPath}/__deck.tsx`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// <stdin>
|
|
295
|
+
module.exports = src_default;
|
|
296
|
+
module.exports.default = src_default;
|
package/index.d.ts
ADDED
package/index.mjs
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import * as fs from "fs/promises";
|
|
3
|
+
|
|
4
|
+
// src/slides.ts
|
|
5
|
+
import matter from "gray-matter";
|
|
6
|
+
import { compile } from "@mdx-js/mdx";
|
|
7
|
+
|
|
8
|
+
// src/codegen.ts
|
|
9
|
+
function extractMainCodeAsChildren(source) {
|
|
10
|
+
const start = source.indexOf("const _components = {");
|
|
11
|
+
const end = source.indexOf("\n}", start);
|
|
12
|
+
const components = source.slice(start, end);
|
|
13
|
+
if (!components) {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
const withWrapper = components.replace(
|
|
17
|
+
/};\s*return/gm,
|
|
18
|
+
"};\n const {wrapper: MDXLayout} = _components;\nreturn"
|
|
19
|
+
);
|
|
20
|
+
const hasLayout = withWrapper.match(/\n\s*return (<>|_jsxs\(_Fragment)/gm);
|
|
21
|
+
if (hasLayout) {
|
|
22
|
+
return withWrapper.replace(/\n\s*return <>/gm, "\nreturn <MDXLayout {...props}>").replace(/<\/>;\s*$/gm, "</MDXLayout>;\n").replace(
|
|
23
|
+
"return _jsxs(_Fragment, {",
|
|
24
|
+
" return _jsx(MDXLayout, {...props,"
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const result = withWrapper.replace(/\n\s*return\s*</gm, "\nreturn <MDXLayout {...props}><").replace(/>;\s*$/gm, "></MDXLayout>;\n").replace(
|
|
28
|
+
"return _jsx(_components",
|
|
29
|
+
" return _jsx(MDXLayout, {...props, children: _jsx(_components"
|
|
30
|
+
).replace(/}\);$/gm, "})});");
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/slides.ts
|
|
35
|
+
async function transformSlidesMdxToReact(sourceContent, {
|
|
36
|
+
production: isProd,
|
|
37
|
+
...options
|
|
38
|
+
}) {
|
|
39
|
+
const { data: metadata, content } = matter(sourceContent);
|
|
40
|
+
const { content: finalContent, inlineModules } = extractInlineModules(
|
|
41
|
+
normalizeNewline(content)
|
|
42
|
+
);
|
|
43
|
+
const slides = finalContent.split("---");
|
|
44
|
+
const enrichedSlides = [];
|
|
45
|
+
const LAYOUT_REGEX = /\S*\nlayout: (.*)/g;
|
|
46
|
+
let frontmatterForNextSlide = null;
|
|
47
|
+
for (const slide of slides) {
|
|
48
|
+
if (LAYOUT_REGEX.test(slide)) {
|
|
49
|
+
frontmatterForNextSlide = matter(`---
|
|
50
|
+
${slide}
|
|
51
|
+
---`).data;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
enrichedSlides.push({
|
|
55
|
+
metadata: frontmatterForNextSlide,
|
|
56
|
+
content: slide
|
|
57
|
+
});
|
|
58
|
+
frontmatterForNextSlide = null;
|
|
59
|
+
}
|
|
60
|
+
const compiledSlides = await Promise.all(
|
|
61
|
+
enrichedSlides.map(async (slide) => {
|
|
62
|
+
const code = addInlineModules(slide.content, inlineModules);
|
|
63
|
+
const normalizedCode = code.replace("process.env", "process\u200B.env");
|
|
64
|
+
const result = await compile(normalizedCode, {
|
|
65
|
+
outputFormat: "program",
|
|
66
|
+
jsx: !isProd,
|
|
67
|
+
providerImportSource: "@mdx-js/react",
|
|
68
|
+
...options
|
|
69
|
+
});
|
|
70
|
+
const mainCode = extractMainCodeAsChildren(result.value.toString());
|
|
71
|
+
return {
|
|
72
|
+
...slide,
|
|
73
|
+
mdxContent: mainCode
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
return addInlineModules(
|
|
78
|
+
`
|
|
79
|
+
import React from 'react';
|
|
80
|
+
${isProd ? 'import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";import {useMDXComponents as _provideComponents} from "@mdx-js/react" ' : "import {useMDXComponents as _provideComponents} from '@mdx-js/react';"}
|
|
81
|
+
|
|
82
|
+
export default {
|
|
83
|
+
metadata: ${JSON.stringify(metadata)},
|
|
84
|
+
slides: [${compiledSlides.map(
|
|
85
|
+
(slide) => `{
|
|
86
|
+
metadata: ${JSON.stringify(slide.metadata)},
|
|
87
|
+
slideComponent: (baseProps) => {
|
|
88
|
+
const props = {...baseProps, frontmatter: ${JSON.stringify(
|
|
89
|
+
slide.metadata
|
|
90
|
+
)} };
|
|
91
|
+
${slide.mdxContent}
|
|
92
|
+
}
|
|
93
|
+
}`
|
|
94
|
+
).join(",")}
|
|
95
|
+
]
|
|
96
|
+
};`,
|
|
97
|
+
inlineModules
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
var MOD_REG = /\\`|`(?:\\`|[^`])*`|(^(?:import|export).*$)/gm;
|
|
101
|
+
function extractInlineModules(source, {
|
|
102
|
+
inlineModules = /* @__PURE__ */ new Set()
|
|
103
|
+
} = {}) {
|
|
104
|
+
const finalContent = source.replace(MOD_REG, (value, group1) => {
|
|
105
|
+
if (!group1) {
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
inlineModules.add(value);
|
|
109
|
+
return "";
|
|
110
|
+
});
|
|
111
|
+
return { content: finalContent, inlineModules };
|
|
112
|
+
}
|
|
113
|
+
function addInlineModules(source, inlineModules) {
|
|
114
|
+
return `
|
|
115
|
+
${[...inlineModules.keys()].join("\n")}
|
|
116
|
+
|
|
117
|
+
${source}
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
var CRLF = "\r\n";
|
|
121
|
+
function normalizeNewline(input) {
|
|
122
|
+
return input.replace(new RegExp(CRLF, "g"), "\n");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/helpers.ts
|
|
126
|
+
function createIndexFile({ entrypoint }) {
|
|
127
|
+
return `<!DOCTYPE html>
|
|
128
|
+
<html lang="en">
|
|
129
|
+
<head>
|
|
130
|
+
<meta charset="utf-8" />
|
|
131
|
+
<title>Title</title>
|
|
132
|
+
|
|
133
|
+
<style>
|
|
134
|
+
html {
|
|
135
|
+
--code-preview-background-color: #222;
|
|
136
|
+
}
|
|
137
|
+
</style>
|
|
138
|
+
|
|
139
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
140
|
+
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
|
141
|
+
</head>
|
|
142
|
+
<body>
|
|
143
|
+
<div id="root"></div>
|
|
144
|
+
<script type="module" src="${entrypoint}"></script>
|
|
145
|
+
</body>
|
|
146
|
+
</html>
|
|
147
|
+
`;
|
|
148
|
+
}
|
|
149
|
+
function createAppDeckFile({ slidePath }) {
|
|
150
|
+
return `import React, { StrictMode } from "react";
|
|
151
|
+
import * as ReactDOM from "react-dom/client";
|
|
152
|
+
import { Deck } from '@gpichot/spectacle-deck';
|
|
153
|
+
|
|
154
|
+
import deck from "${slidePath}";
|
|
155
|
+
|
|
156
|
+
const root = ReactDOM.createRoot(
|
|
157
|
+
document.getElementById("root") as HTMLElement
|
|
158
|
+
);
|
|
159
|
+
root.render(
|
|
160
|
+
<StrictMode>
|
|
161
|
+
<Deck deck={deck} />
|
|
162
|
+
</StrictMode>
|
|
163
|
+
)`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/index.ts
|
|
167
|
+
import * as glob from "glob";
|
|
168
|
+
import path from "path";
|
|
169
|
+
async function checkIfDirectoryExists(path2) {
|
|
170
|
+
try {
|
|
171
|
+
await fs.access(path2);
|
|
172
|
+
return true;
|
|
173
|
+
} catch {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
var src_default = (options) => {
|
|
178
|
+
let isProd = false;
|
|
179
|
+
const deckConfig = {
|
|
180
|
+
decks: []
|
|
181
|
+
};
|
|
182
|
+
return {
|
|
183
|
+
name: "react-deck",
|
|
184
|
+
async config(config) {
|
|
185
|
+
var _a, _b, _c;
|
|
186
|
+
const decks = await glob.glob("./src/**/deck.mdx");
|
|
187
|
+
const inputs = ((_b = (_a = config.build) == null ? void 0 : _a.rollupOptions) == null ? void 0 : _b.input) || {};
|
|
188
|
+
deckConfig.decks = decks.map((deck) => ({
|
|
189
|
+
originalFile: deck,
|
|
190
|
+
index: deck.replace("/deck.mdx", "/index.html").replace("src/", "")
|
|
191
|
+
}));
|
|
192
|
+
const newInputs = decks.reduce((acc, deck) => {
|
|
193
|
+
const deckPath = deck.replace("/deck.mdx", "");
|
|
194
|
+
return [...acc, `${deckPath.replace("src/", "")}/index.html`];
|
|
195
|
+
}, []);
|
|
196
|
+
const finalInputs = typeof inputs === "string" ? [inputs, ...decks] : Array.isArray(inputs) ? [...inputs, ...decks] : { ...inputs, ...newInputs };
|
|
197
|
+
return {
|
|
198
|
+
...config,
|
|
199
|
+
build: {
|
|
200
|
+
...config.build,
|
|
201
|
+
rollupOptions: {
|
|
202
|
+
...(_c = config.build) == null ? void 0 : _c.rollupOptions,
|
|
203
|
+
input: finalInputs
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
},
|
|
208
|
+
configResolved(config) {
|
|
209
|
+
isProd = config.isProduction;
|
|
210
|
+
},
|
|
211
|
+
resolveId(id) {
|
|
212
|
+
if (deckConfig.decks.some((deck) => deck.index === id)) {
|
|
213
|
+
return id;
|
|
214
|
+
}
|
|
215
|
+
if (id.endsWith("__deck.tsx")) {
|
|
216
|
+
return id;
|
|
217
|
+
}
|
|
218
|
+
if (id.endsWith("deck.mdx")) {
|
|
219
|
+
return id;
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
async load(id) {
|
|
223
|
+
const deck = deckConfig.decks.find((deck2) => deck2.index === id);
|
|
224
|
+
if (deck) {
|
|
225
|
+
return createIndexFile({
|
|
226
|
+
entrypoint: deck.originalFile.replace("deck.mdx", "__deck.tsx")
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
if (id.endsWith("__deck.tsx")) {
|
|
230
|
+
const directory = id.replace("/__deck.tsx", "");
|
|
231
|
+
const dir2 = directory.startsWith(".") ? directory : `./${directory}`;
|
|
232
|
+
const path2 = `${dir2}/deck.mdx`;
|
|
233
|
+
if (!await checkIfDirectoryExists(path2)) {
|
|
234
|
+
console.warn(`No deck.mdx file found in ${path2}`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const contentIndex = createAppDeckFile({
|
|
238
|
+
slidePath: `${directory}/deck.mdx`
|
|
239
|
+
});
|
|
240
|
+
return contentIndex;
|
|
241
|
+
}
|
|
242
|
+
if (!id.endsWith("deck.mdx"))
|
|
243
|
+
return;
|
|
244
|
+
const content = await fs.readFile(id, "utf-8");
|
|
245
|
+
const data = await transformSlidesMdxToReact(content, {
|
|
246
|
+
production: isProd,
|
|
247
|
+
...options
|
|
248
|
+
});
|
|
249
|
+
const dir = path.relative(process.cwd(), id);
|
|
250
|
+
return data;
|
|
251
|
+
},
|
|
252
|
+
transformIndexHtml: {
|
|
253
|
+
order: "pre",
|
|
254
|
+
enforce: "pre",
|
|
255
|
+
transform: async (html, ctx) => {
|
|
256
|
+
var _a;
|
|
257
|
+
const originalUrl = ((_a = ctx.originalUrl) == null ? void 0 : _a.split("?")[0]) || "";
|
|
258
|
+
const deckDir = ctx.path.replace("/index.html", "");
|
|
259
|
+
const dir = originalUrl ? `./src${originalUrl}` : `.${deckDir}`;
|
|
260
|
+
const path2 = `${dir}/deck.mdx`;
|
|
261
|
+
if (!await checkIfDirectoryExists(path2)) {
|
|
262
|
+
return html.replace("__SCRIPT__", `./src/main.tsx`);
|
|
263
|
+
}
|
|
264
|
+
const deckPath = dir.startsWith(".") ? dir : `.${dir}`;
|
|
265
|
+
return html.replace("__SCRIPT__", `${deckPath}/__deck.tsx`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
export {
|
|
271
|
+
src_default as default
|
|
272
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-plugin-react-deck",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.cjs",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"module": "index.mjs",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./index.d.ts",
|
|
12
|
+
"require": "./index.cjs",
|
|
13
|
+
"import": "./index.mjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"vite",
|
|
18
|
+
"vite-plugin",
|
|
19
|
+
"react",
|
|
20
|
+
"swc",
|
|
21
|
+
"react-refresh",
|
|
22
|
+
"fast refresh"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@mdx-js/mdx": "^3.0.0",
|
|
26
|
+
"@mdx-js/react": "^3.0.0",
|
|
27
|
+
"glob": "^10.3.10",
|
|
28
|
+
"gray-matter": "^4.0.3"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/slides.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ReactDeckOptions } from "./types";
|
|
2
|
+
type CompileOptions = Pick<ReactDeckOptions, "rehypePlugins">;
|
|
3
|
+
/**
|
|
4
|
+
* Slides are separated by "---" in the markdown file.
|
|
5
|
+
*
|
|
6
|
+
* A file can use frontmatter to specify the title of the slide and internal
|
|
7
|
+
* frontmatter to specify layout like this :
|
|
8
|
+
*
|
|
9
|
+
* ---
|
|
10
|
+
*
|
|
11
|
+
* layout: main
|
|
12
|
+
*
|
|
13
|
+
* ---
|
|
14
|
+
*
|
|
15
|
+
* # Slide 1
|
|
16
|
+
*
|
|
17
|
+
* ---
|
|
18
|
+
*
|
|
19
|
+
* layout: slide2
|
|
20
|
+
*
|
|
21
|
+
* ---
|
|
22
|
+
*
|
|
23
|
+
* # Slide 2
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
export declare function transformSlidesMdxToReact(sourceContent: string, { production: isProd, ...options }: {
|
|
27
|
+
production: boolean;
|
|
28
|
+
} & CompileOptions): Promise<string>;
|
|
29
|
+
export declare function extractInlineModules(source: string, { inlineModules, }?: {
|
|
30
|
+
inlineModules?: Set<string>;
|
|
31
|
+
}): {
|
|
32
|
+
content: string;
|
|
33
|
+
inlineModules: Set<string>;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
package/types.d.ts
ADDED