@rasenganjs/mdx 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.
@@ -0,0 +1,38 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability or other physical appearance.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to creating a positive environment include:
10
+
11
+ - Using welcoming and inclusive language
12
+ - Being respectful of differing viewpoints and experiences
13
+ - Gracefully accepting constructive criticism
14
+ - Focusing on what is best for the community
15
+ - Showing empathy towards other community members
16
+ - Be kind and courteous
17
+
18
+ Examples of unacceptable behavior by participants include:
19
+
20
+ - The use of sexualized language or imagery and unwelcome sexual attention or advances
21
+ - Trolling, insulting/derogatory comments, and personal or political attacks
22
+ - Public or private harassment
23
+ - Publishing others' private information, such as a physical or electronic address, without explicit permission
24
+ - Other conduct which could reasonably be considered inappropriate in a professional setting
25
+
26
+ ## Our Responsibilities
27
+
28
+ Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
29
+
30
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
31
+
32
+ ## Scope
33
+
34
+ This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
35
+
36
+ ## Enforcement
37
+
38
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [reactgx@gmail.com](mailto:reactgx@gmail.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
File without changes
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-Present Dilane Kombou
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # Rasengan MDX Plugin
2
+
3
+ [![npm version](https://badge.fury.io/js/@rasenganjs%mdx.svg)](https://badge.fury.io/js/@rasenganjs%mdx)
4
+ ![NPM Downloads](https://img.shields.io/npm/dm/%40rasenganjs%mdx)
5
+ [![GitHub license](https://img.shields.io/github/license/rasengan-dev/rasengan-mdx-plugin)](https://github.com/rasengan-dev/rasengan-mdx-plugin/blob/main/LICENSE)
6
+
7
+ MDX plugin for Rasengan.Js
8
+
9
+ ## Installation
10
+
11
+ You can install the `@rasenganjs/mdx` package using the following command:
12
+
13
+ ```bash
14
+ npm install @rasenganjs/mdx
15
+ ```
16
+
17
+ or
18
+
19
+ ```bash
20
+ yarn add @rasenganjs/mdx
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ Here is an example of how you can use the `@rasenganjs/mdx` package:
26
+
27
+ ### Basic Usage
28
+
29
+ 1. Setup the `rasengan.config.js` file
30
+
31
+ Import the `mdx` plugin into the `rasengan.config.js` file.
32
+
33
+ ```javascript
34
+ import { defineConfig } from "rasengan";
35
+ import mdx from "@rasenganjs/mdx";
36
+
37
+ export default defineConfig({
38
+ reactStrictMode: true,
39
+
40
+ // Define aliases
41
+ vite: {
42
+ plugins: [
43
+ mdx(),
44
+ ],
45
+ },
46
+ });
47
+ ```
48
+
49
+ 2. Create your `markdown` file.
50
+
51
+ Create a `markdown` file inside the `app` folder with the pattern `[name].page.mdx` or `[name].page.md`
52
+
53
+ ```mdx
54
+ ---
55
+ path: /blog
56
+ metadata:
57
+ title: Blog page
58
+ description: Discover our new blog posts
59
+ ---
60
+
61
+ import Button from "@/components/Button";
62
+
63
+ # Blog page
64
+
65
+ This is a `blog` page.
66
+
67
+ <Button>Click Me</Button>
68
+ ```
69
+
70
+ 3. Use your `markdown` file.
71
+
72
+ Inside the `app.router.ts` file, import your Markdown Component and the `generatePage` function from `@rasenganjs/mdx`
73
+
74
+ ```typescript
75
+ import { RouterComponent, defineRouter } from "rasengan";
76
+ import AppLayout from "@app/app.layout";
77
+ import Blog from "@app/blog.page.mdx";
78
+ import { generatePage } from "@rasenganjs/mdx";
79
+
80
+ const BlogPage = generatePage(Blog);
81
+
82
+ class AppRouter extends RouterComponent {}
83
+
84
+ export default defineRouter({
85
+ imports: [],
86
+ layout: AppLayout,
87
+ pages: [BlogPage],
88
+ })(AppRouter);
89
+ ```
90
+
91
+ Now visit [http://localhost:5320/blog](http://localhost:5320/blog)
92
+
93
+ ## Community
94
+
95
+ The Rasengan.js community can be found on [GitHub Discussions](https://github.com/rasengan-dev/rasenganjs/discussions) where you can ask questions, voice ideas, and share your projects with other people.
96
+
97
+ We also have a [Twitter](https://twitter.com/rasenganjs) account where you can follow us to get the latest news about Rasengan.js.
98
+
99
+ ## License
100
+
101
+ Rasengan.js is [MIT licensed](https://github.com/rasengan-dev/rasengan-image/blob/main/LICENSE).
102
+
103
+ ## Authors
104
+
105
+ Here is the authors list:
106
+
107
+ - Dilane Kombou ([**@dilanekombou**](https://twitter.com/dilanekombou))
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+ import { MDXPageComponent } from "../types/index.js";
3
+ type ComponentWithTextChildrenProps = {
4
+ children: string;
5
+ };
6
+ type MDXRendererProps = {
7
+ children: MDXPageComponent;
8
+ className?: string;
9
+ };
10
+ type CodeBlockProps = ComponentWithTextChildrenProps & {
11
+ className?: string;
12
+ };
13
+ /**
14
+ * A React component that renders a code block with syntax highlighting and a copy button.
15
+ *
16
+ * The component uses the `prism-react-renderer` library to provide syntax highlighting for the code block.
17
+ * It also includes a copy button that allows the user to copy the code to their clipboard.
18
+ *
19
+ * @param {object} props - The component props.
20
+ * @param {string} props.children - The code content to be displayed in the code block.
21
+ * @param {string} [props.className] - The CSS class name to apply to the code block.
22
+ * @returns {React.ReactElement} - The rendered code block component.
23
+ */
24
+ declare const CodeBlock: ({ children, className }: CodeBlockProps) => React.ReactElement;
25
+ declare const SimpleBlock: ({ children }: ComponentWithTextChildrenProps) => React.ReactElement;
26
+ /**
27
+ * Renders an MDX content component with a custom code block component.
28
+ *
29
+ * @param {MDXRendererProps} props - The props for the MDX renderer.
30
+ * @param {React.ReactNode} props.children - The MDX content to render.
31
+ * @param {string} [props.className] - An optional CSS class name to apply to the rendered section.
32
+ * @returns {React.ReactElement} - The rendered MDX content with the custom code block component.
33
+ */
34
+ declare const MDXRenderer: ({ children: MDXContent, className }: MDXRendererProps) => React.ReactElement;
35
+ export { MDXRenderer, CodeBlock, SimpleBlock };
@@ -0,0 +1,92 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { themes, Highlight } from "prism-react-renderer";
3
+ import React from "react";
4
+ /**
5
+ * A React component that renders a code block with syntax highlighting and a copy button.
6
+ *
7
+ * The component uses the `prism-react-renderer` library to provide syntax highlighting for the code block.
8
+ * It also includes a copy button that allows the user to copy the code to their clipboard.
9
+ *
10
+ * @param {object} props - The component props.
11
+ * @param {string} props.children - The code content to be displayed in the code block.
12
+ * @param {string} [props.className] - The CSS class name to apply to the code block.
13
+ * @returns {React.ReactElement} - The rendered code block component.
14
+ */
15
+ const CodeBlock = ({ children, className = "" }) => {
16
+ const language = className.replace(/language-/, "");
17
+ if (!language) {
18
+ return _jsx(SimpleBlock, { children: children });
19
+ }
20
+ return (_jsx(Highlight, { theme: themes.oneDark, code: children.trim(), language: language, children: ({ className, tokens, getLineProps, getTokenProps }) => {
21
+ const [copied, setCopied] = React.useState(false);
22
+ React.useEffect(() => {
23
+ /**
24
+ * Sets the `copied` state to `false` after 2 seconds, effectively hiding the "copied" indicator.
25
+ * This function is called after the user's clipboard is updated with the code content.
26
+ */
27
+ const timer = setTimeout(() => {
28
+ setCopied(false);
29
+ }, 2000);
30
+ return () => clearTimeout(timer);
31
+ }, [copied]);
32
+ /**
33
+ * Copies the trimmed text content of the `children` prop to the user's clipboard.
34
+ * This function is called when the "Copy" button is clicked in the code block component.
35
+ * It sets the `copied` state to `true` for 2 seconds to display a "copied" indicator.
36
+ */
37
+ const handleCopy = () => {
38
+ navigator.clipboard.writeText(children.trim());
39
+ setCopied(true);
40
+ };
41
+ return (_jsxs("pre", { className: className, style: {
42
+ color: "#fff",
43
+ backgroundColor: "#1d2529",
44
+ borderRadius: "20px",
45
+ overflow: "hidden",
46
+ padding: "0px",
47
+ }, children: [_jsxs("div", { style: {
48
+ width: "100%",
49
+ height: "50px",
50
+ backgroundColor: "#28373f",
51
+ display: "flex",
52
+ justifyContent: "space-between",
53
+ alignItems: "center",
54
+ paddingLeft: "20px",
55
+ paddingRight: "20px",
56
+ }, children: [_jsx("span", { children: "Filename" }), _jsx("button", { className: 'copy-button', onClick: handleCopy, children: copied ? (_jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', width: '24', height: '24', color: '#f0f0f0', fill: 'none', children: [_jsx("path", { d: 'M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12Z', stroke: 'currentColor', strokeWidth: '1.5' }), _jsx("path", { d: 'M8 12.5L10.5 15L16 9', stroke: 'currentColor', strokeWidth: '1.5', strokeLinecap: 'round', strokeLinejoin: 'round' })] })) : (_jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', width: '24', height: '24', color: '#f0f0f0', fill: 'none', children: [_jsx("path", { d: 'M9 15C9 12.1716 9 10.7574 9.87868 9.87868C10.7574 9 12.1716 9 15 9L16 9C18.8284 9 20.2426 9 21.1213 9.87868C22 10.7574 22 12.1716 22 15V16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H15C12.1716 22 10.7574 22 9.87868 21.1213C9 20.2426 9 18.8284 9 16L9 15Z', stroke: 'currentColor', strokeWidth: '1.5', strokeLinecap: 'round', strokeLinejoin: 'round' }), _jsx("path", { d: 'M16.9999 9C16.9975 6.04291 16.9528 4.51121 16.092 3.46243C15.9258 3.25989 15.7401 3.07418 15.5376 2.90796C14.4312 2 12.7875 2 9.5 2C6.21252 2 4.56878 2 3.46243 2.90796C3.25989 3.07417 3.07418 3.25989 2.90796 3.46243C2 4.56878 2 6.21252 2 9.5C2 12.7875 2 14.4312 2.90796 15.5376C3.07417 15.7401 3.25989 15.9258 3.46243 16.092C4.51121 16.9528 6.04291 16.9975 9 16.9999', stroke: 'currentColor', strokeWidth: '1.5', strokeLinecap: 'round', strokeLinejoin: 'round' })] })) })] }), _jsx("div", { style: {
57
+ padding: "20px",
58
+ fontSize: "14px",
59
+ }, children: _jsx("code", { children: tokens.map((line, i) => (_jsxs("div", { ...getLineProps({ line }), children: [_jsx("span", { style: {
60
+ opacity: 0.6,
61
+ marginRight: "5px",
62
+ }, children: i + 1 }), _jsx("span", { children: " " }), line.map((token, key) => (_jsx("span", { ...getTokenProps({ token }) }, key)))] }, i))) }) })] }));
63
+ } }));
64
+ };
65
+ const SimpleBlock = ({ children }) => {
66
+ return (_jsx("span", { className: "simple-block", style: {
67
+ fontSize: "14px",
68
+ borderRadius: "5px",
69
+ paddingLeft: "3.6px",
70
+ paddingRight: "3.6px",
71
+ paddingTop: "2px",
72
+ paddingBottom: "2px",
73
+ marginInline: "0px",
74
+ backgroundColor: "#f7f7f7",
75
+ border: "1px solid #f0f0f0",
76
+ }, children: children }));
77
+ };
78
+ /**
79
+ * Renders an MDX content component with a custom code block component.
80
+ *
81
+ * @param {MDXRendererProps} props - The props for the MDX renderer.
82
+ * @param {React.ReactNode} props.children - The MDX content to render.
83
+ * @param {string} [props.className] - An optional CSS class name to apply to the rendered section.
84
+ * @returns {React.ReactElement} - The rendered MDX content with the custom code block component.
85
+ */
86
+ const MDXRenderer = ({ children: MDXContent, className }) => {
87
+ return (_jsx("section", { className: "rasengan-markdown-body " + className, children: _jsx(MDXContent, { components: {
88
+ code: CodeBlock,
89
+ } }) }));
90
+ };
91
+ export { MDXRenderer, CodeBlock, SimpleBlock };
92
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.tsx"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ export * from './types/index.js';
2
+ export * from "./utils/index.js";
3
+ export * from './components/index.js';
4
+ /**
5
+ * A Vite plugin that transforms MDX files into a format that can be used in a RasenganJs application.
6
+ *
7
+ * The plugin performs the following tasks:
8
+ * - Resolves the Vite configuration and stores it for later use.
9
+ * - Transforms MDX files by applying the `@mdx-js/rollup` transformation.
10
+ * - Extracts frontmatter data from the MDX files and creates a `metadata` object.
11
+ * - Appends the `metadata` object to the transformed MDX content.
12
+ *
13
+ * The transformed MDX content can then be used in the RasenganJs application, with the `metadata` object providing additional information about the content.
14
+ */
15
+ export default function rasengan(): {
16
+ name: string;
17
+ enforce: string;
18
+ /**
19
+ * Stores the resolved Vite configuration for later use.
20
+ *
21
+ * @param resolvedConfig - The resolved Vite configuration object.
22
+ */
23
+ configResolved(resolvedConfig: unknown): void;
24
+ /**
25
+ * Transforms an MDX file by applying the `@mdx-js/rollup` transformation, extracting frontmatter data, and appending a `metadata` object to the transformed content.
26
+ *
27
+ * @param code - The content of the MDX file.
28
+ * @param id - The ID of the MDX file.
29
+ * @returns An object containing the transformed MDX code and a source map, or `null` if the file is not an MDX file.
30
+ */
31
+ transform(code: string, id: string): Promise<{
32
+ code: string;
33
+ map: import("rollup").SourceMapInput;
34
+ }>;
35
+ };
package/lib/index.js ADDED
@@ -0,0 +1,72 @@
1
+ import mdx from '@mdx-js/rollup';
2
+ import { createFilter } from "@rollup/pluginutils";
3
+ import matter from 'gray-matter';
4
+ export * from './types/index.js';
5
+ export * from "./utils/index.js";
6
+ export * from './components/index.js';
7
+ /**
8
+ * A Vite plugin that transforms MDX files into a format that can be used in a RasenganJs application.
9
+ *
10
+ * The plugin performs the following tasks:
11
+ * - Resolves the Vite configuration and stores it for later use.
12
+ * - Transforms MDX files by applying the `@mdx-js/rollup` transformation.
13
+ * - Extracts frontmatter data from the MDX files and creates a `metadata` object.
14
+ * - Appends the `metadata` object to the transformed MDX content.
15
+ *
16
+ * The transformed MDX content can then be used in the RasenganJs application, with the `metadata` object providing additional information about the content.
17
+ */
18
+ export default function rasengan() {
19
+ let config;
20
+ const filter = createFilter(/\.mdx?$/);
21
+ return {
22
+ name: "vite-plugin-rasengan-mdx",
23
+ // Apply transformation of the mdx file before other plugins
24
+ enforce: 'pre',
25
+ /**
26
+ * Stores the resolved Vite configuration for later use.
27
+ *
28
+ * @param resolvedConfig - The resolved Vite configuration object.
29
+ */
30
+ configResolved(resolvedConfig) {
31
+ // store the resolved config
32
+ config = resolvedConfig;
33
+ },
34
+ /**
35
+ * Transforms an MDX file by applying the `@mdx-js/rollup` transformation, extracting frontmatter data, and appending a `metadata` object to the transformed content.
36
+ *
37
+ * @param code - The content of the MDX file.
38
+ * @param id - The ID of the MDX file.
39
+ * @returns An object containing the transformed MDX code and a source map, or `null` if the file is not an MDX file.
40
+ */
41
+ async transform(code, id) {
42
+ if (!filter(id)) {
43
+ return null;
44
+ }
45
+ const { content, data: frontmatter } = matter(code);
46
+ // Apply transformation of the mdx file
47
+ const result = await mdx().transform(content, id);
48
+ // Extract the file name from the path
49
+ const fileName = id
50
+ .split("/")
51
+ .pop()
52
+ .replace(/.page.mdx?$/, "");
53
+ // TODO: Consider other params of metadata from frontmatter
54
+ const metadata = {
55
+ path: frontmatter.path || `/${fileName}`,
56
+ metadata: frontmatter.metadata || {
57
+ title: fileName,
58
+ },
59
+ };
60
+ return {
61
+ code: `
62
+ ${result.code}
63
+ const metadata = ${JSON.stringify(metadata)};
64
+
65
+ MDXContent.metadata = metadata;
66
+ `,
67
+ map: result.map,
68
+ };
69
+ },
70
+ };
71
+ }
72
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,gBAAgB,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ;IAC/B,IAAI,MAAe,CAAC;IACpB,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAEvC,OAAO;QACN,IAAI,EAAE,0BAA0B;QAEhC,4DAA4D;QAC5D,OAAO,EAAE,KAAK;QAEd;;;;WAIG;QACH,cAAc,CAAC,cAAuB;YACrC,4BAA4B;YAC5B,MAAM,GAAG,cAAc,CAAC;QACzB,CAAC;QAED;;;;;;WAMG;QACH,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,EAAU;YACvC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjB,OAAO,IAAI,CAAC;YACb,CAAC;YAED,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAEpD,uCAAuC;YACvC,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAElD,sCAAsC;YACtC,MAAM,QAAQ,GAAG,EAAE;iBACjB,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,EAAE;iBACL,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YAE7B,2DAA2D;YAC3D,MAAM,QAAQ,GAAG;gBAChB,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,IAAI,QAAQ,EAAE;gBACxC,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI;oBACjC,KAAK,EAAE,QAAQ;iBACf;aACD,CAAC;YAEF,OAAO;gBACN,IAAI,EAAE;YACE,MAAM,CAAC,IAAI;6BACM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;;;SAG5C;gBACL,GAAG,EAAE,MAAM,CAAC,GAAG;aACf,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ import { type Metadata } from "rasengan";
3
+ /**
4
+ * A React functional component that represents an MDX page.
5
+ *
6
+ * The `MDXPageComponent` type extends the `React.FC<ReactComponentProps>` type, which means it is a React functional component that accepts the standard props for a React component.
7
+ *
8
+ * The `MDXPageComponent` type also has an optional `metadata` property of type `Metadata`, which can be used to store metadata about the page.
9
+ */
10
+ export type MDXPageComponent = React.FC<any> & {
11
+ metadata?: {
12
+ path: string;
13
+ metadata: Metadata;
14
+ };
15
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { type PageComponent } from "rasengan";
2
+ import { MDXPageComponent } from "../types/index.js";
3
+ /**
4
+ * Generates a React component from an MDXPageComponent.
5
+ *
6
+ * @param MDXPage - The MDXPageComponent to generate the React component from.
7
+ * @param className - An optional CSS class name to apply to the MDXRenderer component.
8
+ * @returns A React component that renders the MDXPage content using the MDXRenderer.
9
+ */
10
+ export default function generatePage(MDXPage: MDXPageComponent, className?: string): PageComponent;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { MDXRenderer } from "../components/index.js";
3
+ /**
4
+ * Generates a React component from an MDXPageComponent.
5
+ *
6
+ * @param MDXPage - The MDXPageComponent to generate the React component from.
7
+ * @param className - An optional CSS class name to apply to the MDXRenderer component.
8
+ * @returns A React component that renders the MDXPage content using the MDXRenderer.
9
+ */
10
+ export default function generatePage(MDXPage, className = "") {
11
+ const Page = () => {
12
+ return _jsx(MDXRenderer, { className: className, children: MDXPage });
13
+ };
14
+ Page.path = MDXPage.metadata.path;
15
+ Page.metadata = MDXPage.metadata.metadata;
16
+ return Page;
17
+ }
18
+ //# sourceMappingURL=generate-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-page.js","sourceRoot":"","sources":["../../src/utils/generate-page.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CACnC,OAAyB,EACzB,SAAS,GAAG,EAAE;IAEd,MAAM,IAAI,GAAkB,GAAG,EAAE;QAChC,OAAO,KAAC,WAAW,IAAC,SAAS,EAAE,SAAS,YAAG,OAAO,GAAe,CAAC;IACnE,CAAC,CAAC;IAEF,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAClC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAE1C,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -0,0 +1,2 @@
1
+ import generatePage from "./generate-page.js";
2
+ export { generatePage };
@@ -0,0 +1,3 @@
1
+ import generatePage from "./generate-page.js";
2
+ export { generatePage };
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@rasenganjs/mdx",
3
+ "private": false,
4
+ "version": "1.0.0",
5
+ "description": "RasenganJS plugin for MDX support",
6
+ "type": "module",
7
+ "main": "lib/index.js",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./lib/index.js",
11
+ "require": "./lib/index.js"
12
+ }
13
+ },
14
+ "author": {
15
+ "name": "dilane3",
16
+ "email": "komboudilane125@gmail.com",
17
+ "url": "https://dilane3.com",
18
+ "twitter": "https://twitter.com/dilanekombou",
19
+ "github": "https://github.com/dilane3"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/rasengan-dev/rasengan-mdx-plugin.git",
24
+ "issues": "https://github.com/rasengan-dev/rasengan-mdx-plugin/issues"
25
+ },
26
+ "license": "MIT",
27
+ "scripts": {
28
+ "build:clean": "rm -rf ./lib",
29
+ "build": "npm run build:clean && tsc",
30
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
31
+ "pack": "npm pack --pack-destination ./../../packages/@rasenganjs/mdx",
32
+ "deploy": "npm publish --access public"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "^18.0.0",
36
+ "typescript": "^5.2.2"
37
+ },
38
+ "dependencies": {
39
+ "@mdx-js/rollup": "^3.0.1",
40
+ "@rollup/pluginutils": "^5.1.0",
41
+ "gray-matter": "^4.0.3",
42
+ "prism-react-renderer": "^2.3.1",
43
+ "prismjs": "^1.29.0"
44
+ },
45
+ "peerDependencies": {
46
+ "rasengan": "^1.0.0-beta.35",
47
+ "react": "^18.3.1"
48
+ }
49
+ }
@@ -0,0 +1,219 @@
1
+ import { themes, Highlight } from "prism-react-renderer";
2
+ import React from "react";
3
+ import { MDXPageComponent } from "../types/index.js";
4
+
5
+ type ComponentWithTextChildrenProps = {
6
+ children: string;
7
+ };
8
+
9
+ type MDXRendererProps = {
10
+ children: MDXPageComponent;
11
+ className?: string;
12
+ };
13
+
14
+ type CodeBlockProps = ComponentWithTextChildrenProps & {
15
+ className?: string;
16
+ };
17
+
18
+
19
+ /**
20
+ * A React component that renders a code block with syntax highlighting and a copy button.
21
+ *
22
+ * The component uses the `prism-react-renderer` library to provide syntax highlighting for the code block.
23
+ * It also includes a copy button that allows the user to copy the code to their clipboard.
24
+ *
25
+ * @param {object} props - The component props.
26
+ * @param {string} props.children - The code content to be displayed in the code block.
27
+ * @param {string} [props.className] - The CSS class name to apply to the code block.
28
+ * @returns {React.ReactElement} - The rendered code block component.
29
+ */
30
+ const CodeBlock = ({ children, className = "" }: CodeBlockProps): React.ReactElement => {
31
+ const language = className.replace(/language-/, "");
32
+
33
+ if (!language) {
34
+ return <SimpleBlock>{children}</SimpleBlock>;
35
+ }
36
+
37
+ return (
38
+ <Highlight
39
+ theme={themes.oneDark}
40
+ code={children.trim()}
41
+ language={language}
42
+ >
43
+ {({ className, tokens, getLineProps, getTokenProps }: any) => {
44
+ const [copied, setCopied] = React.useState(false);
45
+
46
+ React.useEffect(() => {
47
+ /**
48
+ * Sets the `copied` state to `false` after 2 seconds, effectively hiding the "copied" indicator.
49
+ * This function is called after the user's clipboard is updated with the code content.
50
+ */
51
+ const timer = setTimeout(() => {
52
+ setCopied(false);
53
+ }, 2000);
54
+
55
+ return () => clearTimeout(timer);
56
+ }, [copied]);
57
+
58
+ /**
59
+ * Copies the trimmed text content of the `children` prop to the user's clipboard.
60
+ * This function is called when the "Copy" button is clicked in the code block component.
61
+ * It sets the `copied` state to `true` for 2 seconds to display a "copied" indicator.
62
+ */
63
+ const handleCopy = () => {
64
+ navigator.clipboard.writeText(children.trim());
65
+ setCopied(true);
66
+ };
67
+
68
+ return (
69
+ <pre
70
+ className={className}
71
+ style={{
72
+ color: "#fff",
73
+ backgroundColor: "#1d2529",
74
+ borderRadius: "20px",
75
+ overflow: "hidden",
76
+ padding: "0px",
77
+ }}
78
+ >
79
+ <div
80
+ style={{
81
+ width: "100%",
82
+ height: "50px",
83
+ backgroundColor: "#28373f",
84
+ display: "flex",
85
+ justifyContent: "space-between",
86
+ alignItems: "center",
87
+ paddingLeft: "20px",
88
+ paddingRight: "20px",
89
+ }}
90
+ >
91
+ <span>Filename</span>
92
+
93
+ <button className='copy-button' onClick={handleCopy}>
94
+ {copied ? (
95
+ <svg
96
+ xmlns='http://www.w3.org/2000/svg'
97
+ viewBox='0 0 24 24'
98
+ width='24'
99
+ height='24'
100
+ color='#f0f0f0'
101
+ fill='none'
102
+ >
103
+ <path
104
+ d='M22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12Z'
105
+ stroke='currentColor'
106
+ strokeWidth='1.5'
107
+ />
108
+ <path
109
+ d='M8 12.5L10.5 15L16 9'
110
+ stroke='currentColor'
111
+ strokeWidth='1.5'
112
+ strokeLinecap='round'
113
+ strokeLinejoin='round'
114
+ />
115
+ </svg>
116
+ ) : (
117
+ <svg
118
+ xmlns='http://www.w3.org/2000/svg'
119
+ viewBox='0 0 24 24'
120
+ width='24'
121
+ height='24'
122
+ color='#f0f0f0'
123
+ fill='none'
124
+ >
125
+ <path
126
+ d='M9 15C9 12.1716 9 10.7574 9.87868 9.87868C10.7574 9 12.1716 9 15 9L16 9C18.8284 9 20.2426 9 21.1213 9.87868C22 10.7574 22 12.1716 22 15V16C22 18.8284 22 20.2426 21.1213 21.1213C20.2426 22 18.8284 22 16 22H15C12.1716 22 10.7574 22 9.87868 21.1213C9 20.2426 9 18.8284 9 16L9 15Z'
127
+ stroke='currentColor'
128
+ strokeWidth='1.5'
129
+ strokeLinecap='round'
130
+ strokeLinejoin='round'
131
+ />
132
+ <path
133
+ d='M16.9999 9C16.9975 6.04291 16.9528 4.51121 16.092 3.46243C15.9258 3.25989 15.7401 3.07418 15.5376 2.90796C14.4312 2 12.7875 2 9.5 2C6.21252 2 4.56878 2 3.46243 2.90796C3.25989 3.07417 3.07418 3.25989 2.90796 3.46243C2 4.56878 2 6.21252 2 9.5C2 12.7875 2 14.4312 2.90796 15.5376C3.07417 15.7401 3.25989 15.9258 3.46243 16.092C4.51121 16.9528 6.04291 16.9975 9 16.9999'
134
+ stroke='currentColor'
135
+ strokeWidth='1.5'
136
+ strokeLinecap='round'
137
+ strokeLinejoin='round'
138
+ />
139
+ </svg>
140
+ )}
141
+ </button>
142
+ </div>
143
+
144
+ <div
145
+ style={{
146
+ padding: "20px",
147
+ fontSize: "14px",
148
+ }}
149
+ >
150
+ <code>
151
+ {tokens.map((line: any, i: number) => (
152
+ <div key={i} {...getLineProps({ line })}>
153
+ <span
154
+ style={{
155
+ opacity: 0.6,
156
+ marginRight: "5px",
157
+ }}
158
+ >
159
+ {i + 1}
160
+ </span>
161
+ <span> </span>
162
+ {line.map((token: any, key: number) => (
163
+ <span key={key} {...getTokenProps({ token })} />
164
+ ))}
165
+ </div>
166
+ ))}
167
+ </code>
168
+ </div>
169
+ </pre>
170
+ );
171
+ }}
172
+ </Highlight>
173
+ );
174
+ };
175
+
176
+ const SimpleBlock = ({ children }: ComponentWithTextChildrenProps): React.ReactElement => {
177
+ return (
178
+ <span
179
+ className="simple-block"
180
+ style={{
181
+ fontSize: "14px",
182
+ borderRadius: "5px",
183
+ paddingLeft: "3.6px",
184
+ paddingRight: "3.6px",
185
+ paddingTop: "2px",
186
+ paddingBottom: "2px",
187
+ marginInline: "0px",
188
+ backgroundColor: "#f7f7f7",
189
+ border: "1px solid #f0f0f0",
190
+ }}
191
+ >{children}</span>
192
+ );
193
+ };
194
+
195
+ /**
196
+ * Renders an MDX content component with a custom code block component.
197
+ *
198
+ * @param {MDXRendererProps} props - The props for the MDX renderer.
199
+ * @param {React.ReactNode} props.children - The MDX content to render.
200
+ * @param {string} [props.className] - An optional CSS class name to apply to the rendered section.
201
+ * @returns {React.ReactElement} - The rendered MDX content with the custom code block component.
202
+ */
203
+ const MDXRenderer = ({ children: MDXContent, className }: MDXRendererProps): React.ReactElement => {
204
+ return (
205
+ <section className={"rasengan-markdown-body " + className}>
206
+ <MDXContent
207
+ components={{
208
+ code: CodeBlock,
209
+ }}
210
+ />
211
+ </section>
212
+ );
213
+ };
214
+
215
+ export {
216
+ MDXRenderer,
217
+ CodeBlock,
218
+ SimpleBlock
219
+ }
package/src/index.ts ADDED
@@ -0,0 +1,82 @@
1
+ import mdx from '@mdx-js/rollup'
2
+ import { createFilter } from "@rollup/pluginutils";
3
+ import matter from 'gray-matter';
4
+
5
+ export * from './types/index.js';
6
+ export * from "./utils/index.js";
7
+ export * from './components/index.js';
8
+
9
+ /**
10
+ * A Vite plugin that transforms MDX files into a format that can be used in a RasenganJs application.
11
+ *
12
+ * The plugin performs the following tasks:
13
+ * - Resolves the Vite configuration and stores it for later use.
14
+ * - Transforms MDX files by applying the `@mdx-js/rollup` transformation.
15
+ * - Extracts frontmatter data from the MDX files and creates a `metadata` object.
16
+ * - Appends the `metadata` object to the transformed MDX content.
17
+ *
18
+ * The transformed MDX content can then be used in the RasenganJs application, with the `metadata` object providing additional information about the content.
19
+ */
20
+ export default function rasengan() {
21
+ let config: unknown;
22
+ const filter = createFilter(/\.mdx?$/);
23
+
24
+ return {
25
+ name: "vite-plugin-rasengan-mdx",
26
+
27
+ // Apply transformation of the mdx file before other plugins
28
+ enforce: 'pre',
29
+
30
+ /**
31
+ * Stores the resolved Vite configuration for later use.
32
+ *
33
+ * @param resolvedConfig - The resolved Vite configuration object.
34
+ */
35
+ configResolved(resolvedConfig: unknown) {
36
+ // store the resolved config
37
+ config = resolvedConfig;
38
+ },
39
+
40
+ /**
41
+ * Transforms an MDX file by applying the `@mdx-js/rollup` transformation, extracting frontmatter data, and appending a `metadata` object to the transformed content.
42
+ *
43
+ * @param code - The content of the MDX file.
44
+ * @param id - The ID of the MDX file.
45
+ * @returns An object containing the transformed MDX code and a source map, or `null` if the file is not an MDX file.
46
+ */
47
+ async transform(code: string, id: string) {
48
+ if (!filter(id)) {
49
+ return null;
50
+ }
51
+
52
+ const { content, data: frontmatter } = matter(code);
53
+
54
+ // Apply transformation of the mdx file
55
+ const result = await mdx().transform(content, id);
56
+
57
+ // Extract the file name from the path
58
+ const fileName = id
59
+ .split("/")
60
+ .pop()
61
+ .replace(/.page.mdx?$/, "");
62
+
63
+ // TODO: Consider other params of metadata from frontmatter
64
+ const metadata = {
65
+ path: frontmatter.path || `/${fileName}`,
66
+ metadata: frontmatter.metadata || {
67
+ title: fileName,
68
+ },
69
+ };
70
+
71
+ return {
72
+ code: `
73
+ ${result.code}
74
+ const metadata = ${JSON.stringify(metadata)};
75
+
76
+ MDXContent.metadata = metadata;
77
+ `,
78
+ map: result.map,
79
+ };
80
+ },
81
+ };
82
+ }
@@ -0,0 +1,15 @@
1
+ import {type Metadata } from "rasengan";
2
+
3
+ /**
4
+ * A React functional component that represents an MDX page.
5
+ *
6
+ * The `MDXPageComponent` type extends the `React.FC<ReactComponentProps>` type, which means it is a React functional component that accepts the standard props for a React component.
7
+ *
8
+ * The `MDXPageComponent` type also has an optional `metadata` property of type `Metadata`, which can be used to store metadata about the page.
9
+ */
10
+ export type MDXPageComponent = React.FC<any> & {
11
+ metadata?: {
12
+ path: string;
13
+ metadata: Metadata;
14
+ };
15
+ };
@@ -0,0 +1,24 @@
1
+ import { type PageComponent } from "rasengan";
2
+ import { MDXPageComponent } from "../types/index.js";
3
+ import { MDXRenderer } from "../components/index.js";
4
+
5
+ /**
6
+ * Generates a React component from an MDXPageComponent.
7
+ *
8
+ * @param MDXPage - The MDXPageComponent to generate the React component from.
9
+ * @param className - An optional CSS class name to apply to the MDXRenderer component.
10
+ * @returns A React component that renders the MDXPage content using the MDXRenderer.
11
+ */
12
+ export default function generatePage(
13
+ MDXPage: MDXPageComponent,
14
+ className = ""
15
+ ): PageComponent {
16
+ const Page: PageComponent = () => {
17
+ return <MDXRenderer className={className}>{MDXPage}</MDXRenderer>;
18
+ };
19
+
20
+ Page.path = MDXPage.metadata.path;
21
+ Page.metadata = MDXPage.metadata.metadata;
22
+
23
+ return Page;
24
+ }
@@ -0,0 +1,3 @@
1
+ import generatePage from "./generate-page.js";
2
+
3
+ export { generatePage };
package/tsconfig.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "lib",
4
+ "rootDir": "src",
5
+ "target": "ESNext",
6
+ "lib": [
7
+ "ES2015",
8
+ "ESNext",
9
+ "dom",
10
+ "dom.iterable",
11
+ "esnext"
12
+ ],
13
+ "allowJs": true,
14
+ "skipLibCheck": true,
15
+ "esModuleInterop": true,
16
+ "allowSyntheticDefaultImports": true,
17
+ "strict": false,
18
+ "forceConsistentCasingInFileNames": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "module": "ESNext",
21
+ "moduleResolution": "bundler",
22
+ "resolveJsonModule": true,
23
+ "isolatedModules": true,
24
+ "jsx": "react-jsx",
25
+ "noEmit": false,
26
+ "declaration": true,
27
+ "sourceMap": true,
28
+
29
+ /* Types */
30
+ "typeRoots": ["node_modules/@types", "src/types"]
31
+ },
32
+ "include": [
33
+ "src",
34
+ "src/types",
35
+ ],
36
+ "exclude": ["node_modules", "lib"]
37
+ }