@codearcade/markdown 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/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # @codearcade/mdx
2
+
3
+ A modern, feature-rich Markdown renderer for React applications. Built for **speed**, **customizability**, and **developer experience**.
4
+
5
+ Packed with **syntax highlighting**, **copy-to-clipboard** functionality, and seamless **dark mode** support out of the box.
6
+
7
+ ---
8
+
9
+ ## ✨ Features
10
+
11
+ - ⚡ **Powered by React Markdown**: Robust and reliable rendering.
12
+ - 🎨 **Theming Support**: First-class support for Light and Dark modes.
13
+ - 💅 **Syntax Highlighting**: Integrated Prism syntax highlighting with **50+ themes** (Dracula, Atom Dark, Night Owl, etc.).
14
+ - 📋 **Copy Code**: Automatic "Copy to Clipboard" button for all code blocks.
15
+ - 🍭 **GFM Support**: GitHub Flavored Markdown (tables, autolinks, strikethrough) enabled by default.
16
+ - 🔌 **Plug & Play**: Works instantly with minimal configuration.
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ Install the package via your preferred package manager:
23
+
24
+ ```bash
25
+ npm install @codearcade/mdx
26
+ # or
27
+ yarn add @codearcade/mdx
28
+ # or
29
+ pnpm add @codearcade/mdx
30
+ # or
31
+ bun add @codearcade/mdx
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ Using `@codearcade/mdx` is simple. Import the component and pass your markdown string.
37
+
38
+ ### Basic Usage
39
+
40
+ ```tsx
41
+ import { MarkdownComponent } from "@codearcade/mdx";
42
+
43
+ const markdown = `
44
+ # Hello World
45
+
46
+ This is a **markdown** component.
47
+
48
+ \`\`\`javascript
49
+ console.log("Hello from CodeArcade!");
50
+ \`\`\`
51
+ `;
52
+
53
+ export default function App() {
54
+ return (
55
+ <div style={{ padding: 20 }}>
56
+ <MarkdownComponent markdownText={markdown} />
57
+ </div>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ### Dark Mode & Custom Themes
63
+
64
+ Easily switch between light and dark modes, and customize the syntax highlighting theme for each mode.
65
+
66
+ ```tsx
67
+ import { useState } from "react";
68
+ import { MarkdownComponent } from "@codearcade/mdx";
69
+
70
+ export default function BlogPost() {
71
+ const [isDarkMode, setIsDarkMode] = useState(false);
72
+
73
+ return (
74
+ <div className={isDarkMode ? "dark-theme" : "light-theme"}>
75
+ <button onClick={() => setIsDarkMode(!isDarkMode)}>Toggle Theme</button>
76
+
77
+ <MarkdownComponent
78
+ markdownText={content}
79
+ theme={isDarkMode ? "dark" : "light"}
80
+ // Customize syntax highlighting themes
81
+ defaultMarkdownThemeLight="atomDark"
82
+ defaultMarkdownThemeDark="dracula"
83
+ />
84
+ </div>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ## API Reference
90
+
91
+ ### `<MarkdownComponent />`
92
+
93
+ | Prop | Type | Default | Description |
94
+ |Text | | | |
95
+ | `markdownText` | `string` | **Required** | The raw markdown string to render. |
96
+ | `theme` | `"light" \| "dark"` | `"light"` | Controls the rendering mode of the component. |
97
+ | `defaultMarkdownThemeLight` | `MarkdownTheme` | `"a11yDark"` | Syntax highlighting theme to use when `theme` is `"light"`. |
98
+ | `defaultMarkdownThemeDark` | `MarkdownTheme` | `"twilight"` | Syntax highlighting theme to use when `theme` is `"dark"`. |
99
+
100
+ ### Available Themes
101
+
102
+ We support a wide range of Prism themes. You can import `prismStyleNames` to see the full list or use it to build a theme selector.
103
+
104
+ ```tsx
105
+ import { prismStyleNames } from "@codearcade/mdx";
106
+
107
+ console.log(prismStyleNames);
108
+ // ["dracula", "atomDark", "nightOwl", "vs", "monokai", ...]
109
+ ```
110
+
111
+ ## License
112
+
113
+ MIT © [CodeArcade](https://github.com/codearcade-io)
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ declare const prismStyleNames: readonly ["a11yDark", "atomDark", "base16AteliersulphurpoolLight", "cb", "coldarkCold", "coldarkDark", "coyWithoutShadows", "coy", "darcula", "dark", "dracula", "duotoneDark", "duotoneEarth", "duotoneForest", "duotoneLight", "duotoneSea", "duotoneSpace", "funky", "ghcolors", "gruvboxDark", "gruvboxLight", "holiTheme", "hopscotch", "lucario", "materialDark", "materialLight", "materialOceanic", "nightOwl", "nord", "okaidia", "oneDark", "oneLight", "pojoaque", "prism", "shadesOfPurple", "solarizedDarkAtom", "solarizedlight", "synthwave84", "tomorrow", "twilight", "vs", "vscDarkPlus", "xonokai", "zTouch"];
3
+ type MarkdownTheme = (typeof prismStyleNames)[number];
4
+ type Theme = "dark" | "light";
5
+ interface MarkdownComponentProps {
6
+ markdownText: string;
7
+ theme?: Theme;
8
+ defaultMarkdownThemeLight?: MarkdownTheme;
9
+ defaultMarkdownThemeDark?: MarkdownTheme;
10
+ }
11
+ declare const MarkdownComponent: React.FC<MarkdownComponentProps>;
12
+ export { MarkdownComponent, prismStyleNames };
package/dist/index.css ADDED
@@ -0,0 +1,181 @@
1
+ /* src/components/markdown.module.css */
2
+ .markdownBody_A8U9fw {
3
+ border-radius: .5rem;
4
+ max-width: 850px;
5
+ padding: 1.5rem;
6
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, Helvetica, Arial, sans-serif;
7
+ font-size: 1rem;
8
+ line-height: 1.75;
9
+ }
10
+
11
+ .markdownBody_A8U9fw h1 {
12
+ font-size: 1.875rem;
13
+ line-height: 2.25rem;
14
+ }
15
+
16
+ .markdownBody_A8U9fw h2 {
17
+ font-size: 1.5rem;
18
+ line-height: 2rem;
19
+ }
20
+
21
+ .markdownBody_A8U9fw h3 {
22
+ font-size: 1.25rem;
23
+ line-height: 1.75rem;
24
+ }
25
+
26
+ .markdownBody_A8U9fw h1, .markdownBody_A8U9fw h2, .markdownBody_A8U9fw h3 {
27
+ margin-bottom: 1rem;
28
+ font-weight: 600;
29
+ }
30
+
31
+ .markdownBody_A8U9fw p {
32
+ margin-bottom: 1rem;
33
+ }
34
+
35
+ .markdownBody_A8U9fw a {
36
+ text-decoration: none;
37
+ }
38
+
39
+ .markdownBody_A8U9fw a:hover {
40
+ text-decoration: underline;
41
+ }
42
+
43
+ .markdownBody_A8U9fw ul, .markdownBody_A8U9fw ol {
44
+ margin-bottom: 1rem;
45
+ padding-left: 1.5rem;
46
+ }
47
+
48
+ .markdownBody_A8U9fw ul {
49
+ list-style-type: disc;
50
+ }
51
+
52
+ .markdownBody_A8U9fw ol {
53
+ list-style-type: decimal;
54
+ }
55
+
56
+ .markdownBody_A8U9fw li {
57
+ margin-bottom: .5rem;
58
+ }
59
+
60
+ .markdownBody_A8U9fw code, .markdownBody_A8U9fw pre {
61
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace;
62
+ }
63
+
64
+ .markdownBody_A8U9fw code {
65
+ border-radius: .25rem;
66
+ padding: .25rem;
67
+ font-size: .875rem;
68
+ }
69
+
70
+ .markdownBody_A8U9fw pre {
71
+ overflow-x: auto;
72
+ border-radius: .5rem;
73
+ margin-bottom: 1rem;
74
+ }
75
+
76
+ .markdownBody_A8U9fw blockquote {
77
+ border-left: 4px solid;
78
+ margin-bottom: 1rem;
79
+ margin-left: 0;
80
+ padding-left: 1rem;
81
+ font-style: italic;
82
+ }
83
+
84
+ .markdownBody_A8U9fw strong {
85
+ font-weight: 700;
86
+ }
87
+
88
+ .markdownBody_A8U9fw em {
89
+ font-style: italic;
90
+ }
91
+
92
+ .markdownBody_A8U9fw del {
93
+ text-decoration: line-through;
94
+ }
95
+
96
+ .markdownBody_A8U9fw hr {
97
+ border: none;
98
+ border-top: 2px solid;
99
+ margin: 1.5rem 0;
100
+ }
101
+
102
+ .markdownBody_A8U9fw table {
103
+ border-collapse: collapse;
104
+ overflow-x: auto;
105
+ width: 100%;
106
+ margin-bottom: 1rem;
107
+ }
108
+
109
+ .markdownBody_A8U9fw th, .markdownBody_A8U9fw td {
110
+ text-align: left;
111
+ border: 1px solid;
112
+ padding: .5rem;
113
+ }
114
+
115
+ .markdownBody_A8U9fw th {
116
+ font-weight: 600;
117
+ }
118
+
119
+ .markdownBody_A8U9fw tr:nth-child(2n) {
120
+ background: none;
121
+ }
122
+
123
+ .markdownBody_A8U9fw > * + * {
124
+ margin-top: 1rem;
125
+ }
126
+
127
+ .markdownBody_A8U9fw h1, .markdownBody_A8U9fw h2, .markdownBody_A8U9fw h3 {
128
+ margin-top: 2rem;
129
+ }
130
+
131
+ .markdownBody_A8U9fw h1:first-child, .markdownBody_A8U9fw h2:first-child, .markdownBody_A8U9fw h3:first-child {
132
+ margin-top: 0;
133
+ }
134
+
135
+ .markdownBody_A8U9fw li > ul, .markdownBody_A8U9fw li > ol {
136
+ margin-top: .5rem;
137
+ }
138
+
139
+ .markdownBody_A8U9fw img {
140
+ display: block;
141
+ max-width: 100%;
142
+ height: auto;
143
+ }
144
+
145
+ .markdownBody_A8U9fw pre {
146
+ margin-top: 1.25rem;
147
+ margin-bottom: 1.25rem;
148
+ }
149
+
150
+ .markdownAction_A8U9fw {
151
+ position: absolute;
152
+ display: flex;
153
+ cursor: pointer;
154
+ opacity: .75;
155
+ color: var(--color-foreground, #171717);
156
+ background-color: #e5e7eb;
157
+ border: none;
158
+ border-radius: .5rem;
159
+ align-items: center;
160
+ gap: .25rem;
161
+ padding: .25rem .5rem;
162
+ transition: opacity .15s ease-in-out;
163
+ font-size: .875rem;
164
+ top: .5rem;
165
+ right: .5rem;
166
+ }
167
+
168
+ .markdownAction_A8U9fw:hover {
169
+ opacity: 1;
170
+ }
171
+
172
+ .markdownAction_A8U9fw svg {
173
+ flex: none;
174
+ width: .85rem;
175
+ height: .85rem;
176
+ }
177
+
178
+ .dark_A8U9fw .markdownAction_A8U9fw {
179
+ color: var(--color-foreground, #fff);
180
+ background-color: #3f3f46;
181
+ }
@@ -0,0 +1 @@
1
+ export * from "./components/markdown";
package/dist/index.js ADDED
@@ -0,0 +1,195 @@
1
+ "use client";
2
+ import "./index.css";
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined")
7
+ return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
10
+
11
+ // src/components/markdown.tsx
12
+ import { useCallback, useEffect, useState } from "react";
13
+ import ReactMarkdown from "react-markdown";
14
+ import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
15
+ import remarkGfm from "remark-gfm";
16
+
17
+ // src/components/markdown.module.css
18
+ var markdown_module_default = {
19
+ markdownBody: "markdownBody_A8U9fw",
20
+ markdownAction: "markdownAction_A8U9fw",
21
+ dark: "dark_A8U9fw"
22
+ };
23
+
24
+ // src/components/markdown.tsx
25
+ import { jsxDEV } from "react/jsx-dev-runtime";
26
+ "use client";
27
+ var prismStyleNames = [
28
+ "a11yDark",
29
+ "atomDark",
30
+ "base16AteliersulphurpoolLight",
31
+ "cb",
32
+ "coldarkCold",
33
+ "coldarkDark",
34
+ "coyWithoutShadows",
35
+ "coy",
36
+ "darcula",
37
+ "dark",
38
+ "dracula",
39
+ "duotoneDark",
40
+ "duotoneEarth",
41
+ "duotoneForest",
42
+ "duotoneLight",
43
+ "duotoneSea",
44
+ "duotoneSpace",
45
+ "funky",
46
+ "ghcolors",
47
+ "gruvboxDark",
48
+ "gruvboxLight",
49
+ "holiTheme",
50
+ "hopscotch",
51
+ "lucario",
52
+ "materialDark",
53
+ "materialLight",
54
+ "materialOceanic",
55
+ "nightOwl",
56
+ "nord",
57
+ "okaidia",
58
+ "oneDark",
59
+ "oneLight",
60
+ "pojoaque",
61
+ "prism",
62
+ "shadesOfPurple",
63
+ "solarizedDarkAtom",
64
+ "solarizedlight",
65
+ "synthwave84",
66
+ "tomorrow",
67
+ "twilight",
68
+ "vs",
69
+ "vscDarkPlus",
70
+ "xonokai",
71
+ "zTouch"
72
+ ];
73
+ var CheckMarkIcon = () => {
74
+ return /* @__PURE__ */ jsxDEV("svg", {
75
+ xmlns: "http://www.w3.org/2000/svg",
76
+ viewBox: "0 0 512 512",
77
+ children: /* @__PURE__ */ jsxDEV("path", {
78
+ fill: "none",
79
+ stroke: "currentColor",
80
+ "stroke-linecap": "round",
81
+ "stroke-linejoin": "round",
82
+ "stroke-width": "24",
83
+ d: "M416 128L192 384l-96-96"
84
+ }, undefined, false, undefined, this)
85
+ }, undefined, false, undefined, this);
86
+ };
87
+ var CopyIcon = () => {
88
+ return /* @__PURE__ */ jsxDEV("svg", {
89
+ xmlns: "http://www.w3.org/2000/svg",
90
+ viewBox: "0 0 512 512",
91
+ children: [
92
+ /* @__PURE__ */ jsxDEV("rect", {
93
+ x: "128",
94
+ y: "128",
95
+ width: "336",
96
+ height: "336",
97
+ rx: "57",
98
+ ry: "57",
99
+ fill: "none",
100
+ stroke: "currentColor",
101
+ "stroke-linejoin": "round",
102
+ "stroke-width": "24"
103
+ }, undefined, false, undefined, this),
104
+ /* @__PURE__ */ jsxDEV("path", {
105
+ d: "M383.5 128l.5-24a56.16 56.16 0 00-56-56H112a64.19 64.19 0 00-64 64v216a56.16 56.16 0 0056 56h24",
106
+ fill: "none",
107
+ stroke: "currentColor",
108
+ "stroke-linecap": "round",
109
+ "stroke-linejoin": "round",
110
+ "stroke-width": "24"
111
+ }, undefined, false, undefined, this)
112
+ ]
113
+ }, undefined, true, undefined, this);
114
+ };
115
+ var CopyToClipboard = ({ text }) => {
116
+ const [isCopied, setIsCopied] = useState(false);
117
+ const copyToClipboard = useCallback(async () => {
118
+ if (isCopied)
119
+ return;
120
+ try {
121
+ await navigator.clipboard.writeText(text);
122
+ setIsCopied(true);
123
+ } catch (err) {
124
+ console.error("Failed to copy text: ", err);
125
+ } finally {
126
+ setTimeout(() => {
127
+ setIsCopied(false);
128
+ }, 2000);
129
+ }
130
+ }, [text, isCopied]);
131
+ return /* @__PURE__ */ jsxDEV("button", {
132
+ onClick: copyToClipboard,
133
+ className: markdown_module_default.markdownAction,
134
+ "aria-label": isCopied ? "Copied to clipboard" : "Copy to clipboard",
135
+ children: [
136
+ isCopied ? /* @__PURE__ */ jsxDEV(CheckMarkIcon, {}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(CopyIcon, {}, undefined, false, undefined, this),
137
+ " ",
138
+ isCopied ? "Copied" : "Copy"
139
+ ]
140
+ }, undefined, true, undefined, this);
141
+ };
142
+ var MarkdownComponent = ({
143
+ markdownText,
144
+ theme = "light",
145
+ defaultMarkdownThemeLight = "a11yDark",
146
+ defaultMarkdownThemeDark = "twilight"
147
+ }) => {
148
+ const [markdownTheme, setMarkdownTheme] = useState();
149
+ useEffect(() => {
150
+ import("react-syntax-highlighter/dist/esm/styles/prism").then((module) => {
151
+ setMarkdownTheme(module[theme === "dark" ? defaultMarkdownThemeDark : defaultMarkdownThemeLight]);
152
+ });
153
+ }, [defaultMarkdownThemeLight, defaultMarkdownThemeDark, theme]);
154
+ return /* @__PURE__ */ jsxDEV("section", {
155
+ className: `${markdown_module_default.markdownBody} ${theme}`,
156
+ children: /* @__PURE__ */ jsxDEV(ReactMarkdown, {
157
+ remarkPlugins: [remarkGfm],
158
+ components: {
159
+ code(props) {
160
+ const { className, children, ref, ...rest } = props;
161
+ const match = /language-(\w+)/.exec(className || "");
162
+ const codeText = String(children).replace(/\n$/, "");
163
+ return match ? /* @__PURE__ */ jsxDEV("div", {
164
+ style: { position: "relative" },
165
+ children: [
166
+ /* @__PURE__ */ jsxDEV(SyntaxHighlighter, {
167
+ ...rest,
168
+ PreTag: "div",
169
+ ref,
170
+ customStyle: { borderRadius: "1rem" },
171
+ language: match[1],
172
+ style: markdownTheme,
173
+ children: codeText
174
+ }, undefined, false, undefined, this),
175
+ /* @__PURE__ */ jsxDEV(CopyToClipboard, {
176
+ text: codeText
177
+ }, undefined, false, undefined, this)
178
+ ]
179
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV("code", {
180
+ ...rest,
181
+ className,
182
+ children
183
+ }, undefined, false, undefined, this);
184
+ }
185
+ },
186
+ children: markdownText
187
+ }, undefined, false, undefined, this)
188
+ }, undefined, false, undefined, this);
189
+ };
190
+ export {
191
+ prismStyleNames,
192
+ MarkdownComponent
193
+ };
194
+
195
+ //# debugId=06022BF521D3780764756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["..\\src\\components\\markdown.tsx"],
4
+ "sourcesContent": [
5
+ "\"use client\";\r\n\r\nimport type { Ref } from \"react\";\r\nimport React, { useCallback, useEffect, useState } from \"react\";\r\nimport ReactMarkdown from \"react-markdown\";\r\nimport { Prism as SyntaxHighlighter } from \"react-syntax-highlighter\";\r\nimport remarkGfm from \"remark-gfm\";\r\n\r\n// @ts-ignore\r\nimport styles from \"./markdown.module.css\";\r\n\r\nconst prismStyleNames = [\r\n \"a11yDark\",\r\n \"atomDark\",\r\n \"base16AteliersulphurpoolLight\",\r\n \"cb\",\r\n \"coldarkCold\",\r\n \"coldarkDark\",\r\n \"coyWithoutShadows\",\r\n \"coy\",\r\n \"darcula\",\r\n \"dark\",\r\n \"dracula\",\r\n \"duotoneDark\",\r\n \"duotoneEarth\",\r\n \"duotoneForest\",\r\n \"duotoneLight\",\r\n \"duotoneSea\",\r\n \"duotoneSpace\",\r\n \"funky\",\r\n \"ghcolors\",\r\n \"gruvboxDark\",\r\n \"gruvboxLight\",\r\n \"holiTheme\",\r\n \"hopscotch\",\r\n \"lucario\",\r\n \"materialDark\",\r\n \"materialLight\",\r\n \"materialOceanic\",\r\n \"nightOwl\",\r\n \"nord\",\r\n \"okaidia\",\r\n \"oneDark\",\r\n \"oneLight\",\r\n \"pojoaque\",\r\n \"prism\",\r\n \"shadesOfPurple\",\r\n \"solarizedDarkAtom\",\r\n \"solarizedlight\",\r\n \"synthwave84\",\r\n \"tomorrow\",\r\n \"twilight\",\r\n \"vs\",\r\n \"vscDarkPlus\",\r\n \"xonokai\",\r\n \"zTouch\",\r\n] as const;\r\n\r\ntype MarkdownTheme = (typeof prismStyleNames)[number];\r\n\r\nconst CheckMarkIcon = () => {\r\n return (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"24\"\r\n d=\"M416 128L192 384l-96-96\"\r\n />\r\n </svg>\r\n );\r\n};\r\n\r\nconst CopyIcon = () => {\r\n return (\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <rect\r\n x=\"128\"\r\n y=\"128\"\r\n width=\"336\"\r\n height=\"336\"\r\n rx=\"57\"\r\n ry=\"57\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"24\"\r\n />\r\n <path\r\n d=\"M383.5 128l.5-24a56.16 56.16 0 00-56-56H112a64.19 64.19 0 00-64 64v216a56.16 56.16 0 0056 56h24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n stroke-width=\"24\"\r\n />\r\n </svg>\r\n );\r\n};\r\n\r\nconst CopyToClipboard = ({ text }: { text: string }) => {\r\n const [isCopied, setIsCopied] = useState(false);\r\n\r\n const copyToClipboard = useCallback(async () => {\r\n if (isCopied) return;\r\n\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n setIsCopied(true);\r\n } catch (err) {\r\n console.error(\"Failed to copy text: \", err);\r\n // Optionally, show a user-friendly error message\r\n } finally {\r\n setTimeout(() => {\r\n setIsCopied(false);\r\n }, 2000);\r\n }\r\n }, [text, isCopied]);\r\n\r\n return (\r\n <button\r\n onClick={copyToClipboard}\r\n className={styles.markdownAction}\r\n aria-label={isCopied ? \"Copied to clipboard\" : \"Copy to clipboard\"}\r\n >\r\n {isCopied ? <CheckMarkIcon /> : <CopyIcon />}{\" \"}\r\n {isCopied ? \"Copied\" : \"Copy\"}\r\n </button>\r\n );\r\n};\r\n\r\ntype Theme = \"dark\" | \"light\";\r\n\r\ninterface MarkdownComponentProps {\r\n markdownText: string;\r\n theme?: Theme;\r\n defaultMarkdownThemeLight?: MarkdownTheme;\r\n defaultMarkdownThemeDark?: MarkdownTheme;\r\n}\r\n\r\ntype SyntaxHighlighterStyle = { [key: string]: React.CSSProperties };\r\n\r\nconst MarkdownComponent: React.FC<MarkdownComponentProps> = ({\r\n markdownText,\r\n theme = \"light\",\r\n defaultMarkdownThemeLight = \"a11yDark\",\r\n defaultMarkdownThemeDark = \"twilight\",\r\n}) => {\r\n const [markdownTheme, setMarkdownTheme] = useState<SyntaxHighlighterStyle>();\r\n\r\n useEffect(() => {\r\n import(\"react-syntax-highlighter/dist/esm/styles/prism\").then((module) => {\r\n setMarkdownTheme(\r\n module[\r\n theme === \"dark\"\r\n ? defaultMarkdownThemeDark\r\n : defaultMarkdownThemeLight\r\n ],\r\n );\r\n });\r\n }, [defaultMarkdownThemeLight, defaultMarkdownThemeDark, theme]);\r\n\r\n return (\r\n <section className={`${styles.markdownBody} ${theme}`}>\r\n <ReactMarkdown\r\n remarkPlugins={[remarkGfm]}\r\n components={{\r\n code(props) {\r\n const { className, children, ref, ...rest } = props;\r\n const match = /language-(\\w+)/.exec(className || \"\");\r\n const codeText = String(children).replace(/\\n$/, \"\");\r\n return match ? (\r\n <div style={{ position: \"relative\" }}>\r\n <SyntaxHighlighter\r\n {...rest}\r\n PreTag=\"div\"\r\n ref={ref as Ref<SyntaxHighlighter>}\r\n customStyle={{ borderRadius: \"1rem\" }}\r\n language={match[1]}\r\n style={markdownTheme}\r\n >\r\n {codeText}\r\n </SyntaxHighlighter>\r\n <CopyToClipboard text={codeText} />\r\n </div>\r\n ) : (\r\n <code {...rest} className={className}>\r\n {children}\r\n </code>\r\n );\r\n },\r\n }}\r\n >\r\n {markdownText}\r\n </ReactMarkdown>\r\n </section>\r\n );\r\n};\r\n\r\nexport { MarkdownComponent, prismStyleNames };\r\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "06022BF521D3780764756E2164756E21",
9
+ "names": []
10
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@codearcade/markdown",
3
+ "type": "module",
4
+ "version": "1.0.0",
5
+ "module": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "license": "MIT",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "sideEffects": [
15
+ "dist/*.css"
16
+ ],
17
+ "scripts": {
18
+ "build": "bun ./builder.ts && bun run generate-types",
19
+ "prepublishOnly": "bun run build",
20
+ "generate-types": "bunx tsc --emitDeclarationOnly --declaration --outDir dist",
21
+ "clear": "rm -rf dist"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "homepage": "https://github.com/codearcade-io/markdown.git#readme",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/codearcade-io/markdown.git"
33
+ },
34
+ "bugs": "https://github.com/codearcade-io/markdown/issues",
35
+ "author": "Abhishek Singh <official.6packprogrammer@gmail.com>",
36
+ "devDependencies": {
37
+ "@types/bun": "^1.2.20",
38
+ "@types/react-syntax-highlighter": "^15.5.13",
39
+ "tslib": "^2.8.1",
40
+ "typedoc": "^0.28.10"
41
+ },
42
+ "peerDependencies": {
43
+ "react": ">=18",
44
+ "react-dom": ">=18"
45
+ },
46
+ "dependencies": {
47
+ "react-markdown": "^10.1.0",
48
+ "react-syntax-highlighter": "^16.1.0",
49
+ "remark-gfm": "^4.0.1"
50
+ }
51
+ }