@codearcade/markdown 1.0.1 → 1.2.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 +38 -24
- package/dist/components/icons.d.ts +3 -0
- package/dist/components/markdown.d.ts +13 -7
- package/dist/constants/theme.d.ts +6 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +204 -77
- package/package.json +2 -2
- package/dist/index.js.map +0 -10
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
# @codearcade/
|
|
1
|
+
# @codearcade/markdown
|
|
2
2
|
|
|
3
3
|
A modern, feature-rich Markdown renderer for React applications. Built for **speed**, **customizability**, and **developer experience**.
|
|
4
4
|
|
|
5
|
-
Packed with **syntax highlighting
|
|
5
|
+
Packed with **dynamic syntax highlighting** (lazy-loaded for zero bloat), **copy-to-clipboard** functionality, and seamless **dark mode** support out of the box.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## ✨ Features
|
|
10
10
|
|
|
11
11
|
- ⚡ **Powered by React Markdown**: Robust and reliable rendering.
|
|
12
|
+
- 🚀 **Zero Initial Bloat**: Syntax highlighters and themes are dynamically lazy-loaded only when needed!
|
|
12
13
|
- 🎨 **Theming Support**: First-class support for Light and Dark modes.
|
|
13
|
-
- 💅 **Syntax Highlighting**:
|
|
14
|
+
- 💅 **Dual Engine Syntax Highlighting**: Choose between **Prism** or **Highlight.js** under the hood, with access to over 100+ combined themes.
|
|
14
15
|
- 📋 **Copy Code**: Automatic "Copy to Clipboard" button for all code blocks.
|
|
15
16
|
- 🍭 **GFM Support**: GitHub Flavored Markdown (tables, autolinks, strikethrough) enabled by default.
|
|
16
|
-
- 🔌 **Plug & Play**: Works instantly with minimal configuration.
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -22,38 +22,39 @@ Packed with **syntax highlighting**, **copy-to-clipboard** functionality, and se
|
|
|
22
22
|
Install the package via your preferred package manager:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npm install @codearcade/
|
|
25
|
+
npm install @codearcade/markdown
|
|
26
26
|
# or
|
|
27
|
-
yarn add @codearcade/
|
|
27
|
+
yarn add @codearcade/markdown
|
|
28
28
|
# or
|
|
29
|
-
pnpm add @codearcade/
|
|
29
|
+
pnpm add @codearcade/markdown
|
|
30
30
|
# or
|
|
31
|
-
bun add @codearcade/
|
|
31
|
+
bun add @codearcade/markdown
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## Usage
|
|
35
35
|
|
|
36
|
-
Using `@codearcade/
|
|
36
|
+
Using `@codearcade/markdown` is simple. Import the component, select your engine (`prism` or `hljs`), and pass your markdown string.
|
|
37
37
|
|
|
38
38
|
### Basic Usage
|
|
39
39
|
|
|
40
40
|
```tsx
|
|
41
|
-
import { MarkdownComponent } from "@codearcade/
|
|
41
|
+
import { MarkdownComponent } from "@codearcade/markdown";
|
|
42
42
|
|
|
43
43
|
const markdown = `
|
|
44
44
|
# Hello World
|
|
45
45
|
|
|
46
46
|
This is a **markdown** component.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
```javascript
|
|
49
49
|
console.log("Hello from CodeArcade!");
|
|
50
|
-
|
|
50
|
+
```
|
|
51
51
|
`;
|
|
52
52
|
|
|
53
53
|
export default function App() {
|
|
54
54
|
return (
|
|
55
55
|
<div style={{ padding: 20 }}>
|
|
56
|
-
|
|
56
|
+
{/* The engine prop is required! Choose "prism" or "hljs" */}
|
|
57
|
+
<MarkdownComponent engine="prism" markdownText={markdown} />
|
|
57
58
|
</div>
|
|
58
59
|
);
|
|
59
60
|
}
|
|
@@ -61,11 +62,11 @@ export default function App() {
|
|
|
61
62
|
|
|
62
63
|
### Dark Mode & Custom Themes
|
|
63
64
|
|
|
64
|
-
Easily switch between light and dark modes, and customize the syntax highlighting theme
|
|
65
|
+
Easily switch between light and dark modes, and customize the syntax highlighting theme. Because this component is fully strongly-typed, your IDE will auto-complete the available themes based on the engine you select!
|
|
65
66
|
|
|
66
67
|
```tsx
|
|
67
68
|
import { useState } from "react";
|
|
68
|
-
import { MarkdownComponent } from "@codearcade/
|
|
69
|
+
import { MarkdownComponent } from "@codearcade/markdown";
|
|
69
70
|
|
|
70
71
|
export default function BlogPost() {
|
|
71
72
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
|
@@ -75,9 +76,10 @@ export default function BlogPost() {
|
|
|
75
76
|
<button onClick={() => setIsDarkMode(!isDarkMode)}>Toggle Theme</button>
|
|
76
77
|
|
|
77
78
|
<MarkdownComponent
|
|
78
|
-
|
|
79
|
+
engine="prism"
|
|
80
|
+
markdownText={`console.log('test')`}
|
|
79
81
|
theme={isDarkMode ? "dark" : "light"}
|
|
80
|
-
//
|
|
82
|
+
// These will auto-complete to valid Prism themes!
|
|
81
83
|
defaultMarkdownThemeLight="atomDark"
|
|
82
84
|
defaultMarkdownThemeDark="dracula"
|
|
83
85
|
/>
|
|
@@ -91,23 +93,35 @@ export default function BlogPost() {
|
|
|
91
93
|
### `<MarkdownComponent />`
|
|
92
94
|
|
|
93
95
|
| Prop | Type | Default | Description |
|
|
94
|
-
|
|
96
|
+
|---|---|---|---|
|
|
97
|
+
| `engine` | `"prism" \| "hljs"` | **Required** | The syntax highlighting engine to power the code blocks. |
|
|
95
98
|
| `markdownText` | `string` | **Required** | The raw markdown string to render. |
|
|
96
|
-
| `theme` | `"light" \| "dark"` | `"light"` | Controls the rendering mode of the component. |
|
|
97
|
-
| `defaultMarkdownThemeLight` | `
|
|
98
|
-
| `defaultMarkdownThemeDark` | `
|
|
99
|
+
| `theme` | `"light" \| "dark"` | `"light"` | Controls the rendering mode of the surrounding component. |
|
|
100
|
+
| `defaultMarkdownThemeLight` | `string` | `"a11yDark"` | Syntax highlighting theme to use when `theme` is `"light"`. Allowed strings change based on the `engine`. |
|
|
101
|
+
| `defaultMarkdownThemeDark` | `string` | `"twilight"` (Prism) / `"vs2015"` (HLJS) | Syntax highlighting theme to use when `theme` is `"dark"`. Allowed strings change based on the `engine`. |
|
|
99
102
|
|
|
100
103
|
### Available Themes
|
|
101
104
|
|
|
102
|
-
We support a wide range of
|
|
105
|
+
We support a wide range of syntax highlighting themes. You can import the arrays directly if you want to build a theme-selector UI in your app!
|
|
106
|
+
|
|
107
|
+
#### Prism Themes
|
|
103
108
|
|
|
104
109
|
```tsx
|
|
105
|
-
import { prismStyleNames } from "@codearcade/
|
|
110
|
+
import { prismStyleNames } from "@codearcade/markdown";
|
|
106
111
|
|
|
107
112
|
console.log(prismStyleNames);
|
|
108
113
|
// ["dracula", "atomDark", "nightOwl", "vs", "monokai", ...]
|
|
109
114
|
```
|
|
110
115
|
|
|
116
|
+
#### Highlight.js Themes
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
import { hljsStyleNames } from "@codearcade/markdown";
|
|
120
|
+
|
|
121
|
+
console.log(hljsStyleNames);
|
|
122
|
+
// ["atom-one-dark", "atom-one-light", "base16/darcula", "github-dark", "nord", ...]
|
|
123
|
+
```
|
|
124
|
+
|
|
111
125
|
## License
|
|
112
126
|
|
|
113
|
-
MIT © [CodeArcade](https://github.com/codearcade-io)
|
|
127
|
+
MIT © [CodeArcade](https://github.com/codearcade-io)
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
type MarkdownTheme = (typeof prismStyleNames)[number];
|
|
2
|
+
import { HljsTheme, PrismTheme } from "../constants/theme";
|
|
4
3
|
type Theme = "dark" | "light";
|
|
5
|
-
|
|
4
|
+
type MarkdownComponentProps = {
|
|
5
|
+
engine: "prism";
|
|
6
|
+
defaultMarkdownThemeLight?: PrismTheme;
|
|
7
|
+
theme?: Theme;
|
|
8
|
+
markdownText: string;
|
|
9
|
+
defaultMarkdownThemeDark?: PrismTheme;
|
|
10
|
+
} | {
|
|
11
|
+
engine: "hljs";
|
|
12
|
+
defaultMarkdownThemeLight?: HljsTheme;
|
|
6
13
|
markdownText: string;
|
|
7
14
|
theme?: Theme;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
15
|
+
defaultMarkdownThemeDark?: HljsTheme;
|
|
16
|
+
};
|
|
11
17
|
declare const MarkdownComponent: React.FC<MarkdownComponentProps>;
|
|
12
|
-
export { MarkdownComponent
|
|
18
|
+
export { MarkdownComponent };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
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"];
|
|
2
|
+
declare const hljsStyleNames: readonly ["a11yDark", "a11yLight", "agate", "anOldHope", "androidstudio", "arduinoLight", "arta", "ascetic", "atelierCaveDark", "atelierCaveLight", "atelierDuneDark", "atelierDuneLight", "atelierEstuaryDark", "atelierEstuaryLight", "atelierForestDark", "atelierForestLight", "atelierHeathDark", "atelierHeathLight", "atelierLakesideDark", "atelierLakesideLight", "atelierPlateauDark", "atelierPlateauLight", "atelierSavannaDark", "atelierSavannaLight", "atelierSeasideDark", "atelierSeasideLight", "atelierSulphurpoolDark", "atelierSulphurpoolLight", "atomOneDarkReasonable", "atomOneDark", "atomOneLight", "brownPaper", "codepenEmbed", "colorBrewer", "darcula", "dark", "defaultStyle", "docco", "dracula", "far", "foundation", "githubGist", "github", "gml", "googlecode", "gradientDark", "grayscale", "gruvboxDark", "gruvboxLight", "hopscotch", "hybrid", "idea", "irBlack", "isblEditorDark", "isblEditorLight", "kimbieDark", "kimbieLight", "lightfair", "lioshi", "magula", "monoBlue", "monokaiSublime", "monokai", "nightOwl", "nnfxDark", "nnfx", "nord", "obsidian", "ocean", "paraisoDark", "paraisoLight", "pojoaque", "purebasic", "qtcreatorDark", "qtcreatorLight", "railscasts", "rainbow", "routeros", "schoolBook", "shadesOfPurple", "solarizedDark", "solarizedLight", "srcery", "stackoverflowDark", "stackoverflowLight", "sunburst", "tomorrowNightBlue", "tomorrowNightBright", "tomorrowNightEighties", "tomorrowNight", "tomorrow", "vs", "vs2015", "xcode", "xt256", "zenburn"];
|
|
3
|
+
type PrismTheme = (typeof prismStyleNames)[number];
|
|
4
|
+
type HljsTheme = (typeof hljsStyleNames)[number];
|
|
5
|
+
export { prismStyleNames, hljsStyleNames };
|
|
6
|
+
export type { PrismTheme, HljsTheme };
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -11,7 +11,6 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
11
11
|
// src/components/markdown.tsx
|
|
12
12
|
import { useCallback, useEffect, useState } from "react";
|
|
13
13
|
import ReactMarkdown from "react-markdown";
|
|
14
|
-
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
|
15
14
|
import remarkGfm from "remark-gfm";
|
|
16
15
|
|
|
17
16
|
// src/components/markdown.module.css
|
|
@@ -21,60 +20,13 @@ var markdown_module_default = {
|
|
|
21
20
|
dark: "dark_A8U9fw"
|
|
22
21
|
};
|
|
23
22
|
|
|
24
|
-
// src/components/
|
|
25
|
-
import {
|
|
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
|
-
];
|
|
23
|
+
// src/components/icons.tsx
|
|
24
|
+
import { jsx } from "react/jsx-runtime";
|
|
73
25
|
var CheckMarkIcon = () => {
|
|
74
|
-
return /* @__PURE__ */
|
|
26
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
75
27
|
xmlns: "http://www.w3.org/2000/svg",
|
|
76
28
|
viewBox: "0 0 512 512",
|
|
77
|
-
children: /* @__PURE__ */
|
|
29
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
78
30
|
fill: "none",
|
|
79
31
|
stroke: "currentColor",
|
|
80
32
|
"stroke-linecap": "round",
|
|
@@ -85,11 +37,11 @@ var CheckMarkIcon = () => {
|
|
|
85
37
|
}, undefined, false, undefined, this);
|
|
86
38
|
};
|
|
87
39
|
var CopyIcon = () => {
|
|
88
|
-
return /* @__PURE__ */
|
|
40
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
89
41
|
xmlns: "http://www.w3.org/2000/svg",
|
|
90
42
|
viewBox: "0 0 512 512",
|
|
91
43
|
children: [
|
|
92
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ jsx("rect", {
|
|
93
45
|
x: "128",
|
|
94
46
|
y: "128",
|
|
95
47
|
width: "336",
|
|
@@ -101,7 +53,7 @@ var CopyIcon = () => {
|
|
|
101
53
|
"stroke-linejoin": "round",
|
|
102
54
|
"stroke-width": "24"
|
|
103
55
|
}, undefined, false, undefined, this),
|
|
104
|
-
/* @__PURE__ */
|
|
56
|
+
/* @__PURE__ */ jsx("path", {
|
|
105
57
|
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
58
|
fill: "none",
|
|
107
59
|
stroke: "currentColor",
|
|
@@ -112,6 +64,10 @@ var CopyIcon = () => {
|
|
|
112
64
|
]
|
|
113
65
|
}, undefined, true, undefined, this);
|
|
114
66
|
};
|
|
67
|
+
|
|
68
|
+
// src/components/markdown.tsx
|
|
69
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
70
|
+
"use client";
|
|
115
71
|
var CopyToClipboard = ({ text }) => {
|
|
116
72
|
const [isCopied, setIsCopied] = useState(false);
|
|
117
73
|
const copyToClipboard = useCallback(async () => {
|
|
@@ -128,42 +84,69 @@ var CopyToClipboard = ({ text }) => {
|
|
|
128
84
|
}, 2000);
|
|
129
85
|
}
|
|
130
86
|
}, [text, isCopied]);
|
|
131
|
-
return /* @__PURE__ */
|
|
87
|
+
return /* @__PURE__ */ jsx2("button", {
|
|
132
88
|
onClick: copyToClipboard,
|
|
133
89
|
className: markdown_module_default.markdownAction,
|
|
134
90
|
"aria-label": isCopied ? "Copied to clipboard" : "Copy to clipboard",
|
|
135
91
|
children: [
|
|
136
|
-
isCopied ? /* @__PURE__ */
|
|
92
|
+
isCopied ? /* @__PURE__ */ jsx2(CheckMarkIcon, {}, undefined, false, undefined, this) : /* @__PURE__ */ jsx2(CopyIcon, {}, undefined, false, undefined, this),
|
|
137
93
|
" ",
|
|
138
94
|
isCopied ? "Copied" : "Copy"
|
|
139
95
|
]
|
|
140
96
|
}, undefined, true, undefined, this);
|
|
141
97
|
};
|
|
142
|
-
var MarkdownComponent = ({
|
|
143
|
-
markdownText,
|
|
144
|
-
theme = "light",
|
|
145
|
-
defaultMarkdownThemeLight = "a11yDark",
|
|
146
|
-
defaultMarkdownThemeDark = "twilight"
|
|
147
|
-
}) => {
|
|
98
|
+
var MarkdownComponent = (props) => {
|
|
99
|
+
const { markdownText, theme = "light", engine = "prism" } = props;
|
|
148
100
|
const [markdownTheme, setMarkdownTheme] = useState();
|
|
101
|
+
const [Highlighter, setHighlighter] = useState();
|
|
149
102
|
useEffect(() => {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
103
|
+
let isMounted = true;
|
|
104
|
+
const loadDependencies = async () => {
|
|
105
|
+
try {
|
|
106
|
+
let themeModule;
|
|
107
|
+
let highlighterModule;
|
|
108
|
+
let selectedThemeName;
|
|
109
|
+
if (engine === "hljs") {
|
|
110
|
+
const hljsProps = props;
|
|
111
|
+
selectedThemeName = theme === "dark" ? hljsProps.defaultMarkdownThemeDark ?? "vs2015" : hljsProps.defaultMarkdownThemeLight ?? "a11yDark";
|
|
112
|
+
[highlighterModule, themeModule] = await Promise.all([
|
|
113
|
+
import("react-syntax-highlighter"),
|
|
114
|
+
import("react-syntax-highlighter/dist/esm/styles/hljs")
|
|
115
|
+
]);
|
|
116
|
+
} else {
|
|
117
|
+
const prismProps = props;
|
|
118
|
+
selectedThemeName = theme === "dark" ? prismProps.defaultMarkdownThemeDark ?? "twilight" : prismProps.defaultMarkdownThemeLight ?? "a11yDark";
|
|
119
|
+
[highlighterModule, themeModule] = await Promise.all([
|
|
120
|
+
import("react-syntax-highlighter/dist/esm/prism"),
|
|
121
|
+
import("react-syntax-highlighter/dist/esm/styles/prism")
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
124
|
+
if (isMounted) {
|
|
125
|
+
setHighlighter(() => highlighterModule.default);
|
|
126
|
+
setMarkdownTheme(themeModule[selectedThemeName]);
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("Failed to load syntax highlighter dependencies:", error);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
loadDependencies();
|
|
133
|
+
return () => {
|
|
134
|
+
isMounted = false;
|
|
135
|
+
};
|
|
136
|
+
}, [engine, theme]);
|
|
137
|
+
return /* @__PURE__ */ jsx2("section", {
|
|
155
138
|
className: `${markdown_module_default.markdownBody} ${theme}`,
|
|
156
|
-
children: /* @__PURE__ */
|
|
139
|
+
children: /* @__PURE__ */ jsx2(ReactMarkdown, {
|
|
157
140
|
remarkPlugins: [remarkGfm],
|
|
158
141
|
components: {
|
|
159
|
-
code(
|
|
160
|
-
const { className, children, ref, ...rest } =
|
|
142
|
+
code(props2) {
|
|
143
|
+
const { className, children, ref, ...rest } = props2;
|
|
161
144
|
const match = /language-(\w+)/.exec(className || "");
|
|
162
145
|
const codeText = String(children).replace(/\n$/, "");
|
|
163
|
-
return match ? /* @__PURE__ */
|
|
146
|
+
return match && Highlighter ? /* @__PURE__ */ jsx2("div", {
|
|
164
147
|
style: { position: "relative" },
|
|
165
148
|
children: [
|
|
166
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ jsx2(Highlighter, {
|
|
167
150
|
...rest,
|
|
168
151
|
PreTag: "div",
|
|
169
152
|
ref,
|
|
@@ -172,11 +155,11 @@ var MarkdownComponent = ({
|
|
|
172
155
|
style: markdownTheme,
|
|
173
156
|
children: codeText
|
|
174
157
|
}, undefined, false, undefined, this),
|
|
175
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ jsx2(CopyToClipboard, {
|
|
176
159
|
text: codeText
|
|
177
160
|
}, undefined, false, undefined, this)
|
|
178
161
|
]
|
|
179
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
162
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx2("code", {
|
|
180
163
|
...rest,
|
|
181
164
|
className,
|
|
182
165
|
children
|
|
@@ -187,9 +170,153 @@ var MarkdownComponent = ({
|
|
|
187
170
|
}, undefined, false, undefined, this)
|
|
188
171
|
}, undefined, false, undefined, this);
|
|
189
172
|
};
|
|
173
|
+
// src/constants/theme.ts
|
|
174
|
+
var prismStyleNames = [
|
|
175
|
+
"a11yDark",
|
|
176
|
+
"atomDark",
|
|
177
|
+
"base16AteliersulphurpoolLight",
|
|
178
|
+
"cb",
|
|
179
|
+
"coldarkCold",
|
|
180
|
+
"coldarkDark",
|
|
181
|
+
"coyWithoutShadows",
|
|
182
|
+
"coy",
|
|
183
|
+
"darcula",
|
|
184
|
+
"dark",
|
|
185
|
+
"dracula",
|
|
186
|
+
"duotoneDark",
|
|
187
|
+
"duotoneEarth",
|
|
188
|
+
"duotoneForest",
|
|
189
|
+
"duotoneLight",
|
|
190
|
+
"duotoneSea",
|
|
191
|
+
"duotoneSpace",
|
|
192
|
+
"funky",
|
|
193
|
+
"ghcolors",
|
|
194
|
+
"gruvboxDark",
|
|
195
|
+
"gruvboxLight",
|
|
196
|
+
"holiTheme",
|
|
197
|
+
"hopscotch",
|
|
198
|
+
"lucario",
|
|
199
|
+
"materialDark",
|
|
200
|
+
"materialLight",
|
|
201
|
+
"materialOceanic",
|
|
202
|
+
"nightOwl",
|
|
203
|
+
"nord",
|
|
204
|
+
"okaidia",
|
|
205
|
+
"oneDark",
|
|
206
|
+
"oneLight",
|
|
207
|
+
"pojoaque",
|
|
208
|
+
"prism",
|
|
209
|
+
"shadesOfPurple",
|
|
210
|
+
"solarizedDarkAtom",
|
|
211
|
+
"solarizedlight",
|
|
212
|
+
"synthwave84",
|
|
213
|
+
"tomorrow",
|
|
214
|
+
"twilight",
|
|
215
|
+
"vs",
|
|
216
|
+
"vscDarkPlus",
|
|
217
|
+
"xonokai",
|
|
218
|
+
"zTouch"
|
|
219
|
+
];
|
|
220
|
+
var hljsStyleNames = [
|
|
221
|
+
"a11yDark",
|
|
222
|
+
"a11yLight",
|
|
223
|
+
"agate",
|
|
224
|
+
"anOldHope",
|
|
225
|
+
"androidstudio",
|
|
226
|
+
"arduinoLight",
|
|
227
|
+
"arta",
|
|
228
|
+
"ascetic",
|
|
229
|
+
"atelierCaveDark",
|
|
230
|
+
"atelierCaveLight",
|
|
231
|
+
"atelierDuneDark",
|
|
232
|
+
"atelierDuneLight",
|
|
233
|
+
"atelierEstuaryDark",
|
|
234
|
+
"atelierEstuaryLight",
|
|
235
|
+
"atelierForestDark",
|
|
236
|
+
"atelierForestLight",
|
|
237
|
+
"atelierHeathDark",
|
|
238
|
+
"atelierHeathLight",
|
|
239
|
+
"atelierLakesideDark",
|
|
240
|
+
"atelierLakesideLight",
|
|
241
|
+
"atelierPlateauDark",
|
|
242
|
+
"atelierPlateauLight",
|
|
243
|
+
"atelierSavannaDark",
|
|
244
|
+
"atelierSavannaLight",
|
|
245
|
+
"atelierSeasideDark",
|
|
246
|
+
"atelierSeasideLight",
|
|
247
|
+
"atelierSulphurpoolDark",
|
|
248
|
+
"atelierSulphurpoolLight",
|
|
249
|
+
"atomOneDarkReasonable",
|
|
250
|
+
"atomOneDark",
|
|
251
|
+
"atomOneLight",
|
|
252
|
+
"brownPaper",
|
|
253
|
+
"codepenEmbed",
|
|
254
|
+
"colorBrewer",
|
|
255
|
+
"darcula",
|
|
256
|
+
"dark",
|
|
257
|
+
"defaultStyle",
|
|
258
|
+
"docco",
|
|
259
|
+
"dracula",
|
|
260
|
+
"far",
|
|
261
|
+
"foundation",
|
|
262
|
+
"githubGist",
|
|
263
|
+
"github",
|
|
264
|
+
"gml",
|
|
265
|
+
"googlecode",
|
|
266
|
+
"gradientDark",
|
|
267
|
+
"grayscale",
|
|
268
|
+
"gruvboxDark",
|
|
269
|
+
"gruvboxLight",
|
|
270
|
+
"hopscotch",
|
|
271
|
+
"hybrid",
|
|
272
|
+
"idea",
|
|
273
|
+
"irBlack",
|
|
274
|
+
"isblEditorDark",
|
|
275
|
+
"isblEditorLight",
|
|
276
|
+
"kimbieDark",
|
|
277
|
+
"kimbieLight",
|
|
278
|
+
"lightfair",
|
|
279
|
+
"lioshi",
|
|
280
|
+
"magula",
|
|
281
|
+
"monoBlue",
|
|
282
|
+
"monokaiSublime",
|
|
283
|
+
"monokai",
|
|
284
|
+
"nightOwl",
|
|
285
|
+
"nnfxDark",
|
|
286
|
+
"nnfx",
|
|
287
|
+
"nord",
|
|
288
|
+
"obsidian",
|
|
289
|
+
"ocean",
|
|
290
|
+
"paraisoDark",
|
|
291
|
+
"paraisoLight",
|
|
292
|
+
"pojoaque",
|
|
293
|
+
"purebasic",
|
|
294
|
+
"qtcreatorDark",
|
|
295
|
+
"qtcreatorLight",
|
|
296
|
+
"railscasts",
|
|
297
|
+
"rainbow",
|
|
298
|
+
"routeros",
|
|
299
|
+
"schoolBook",
|
|
300
|
+
"shadesOfPurple",
|
|
301
|
+
"solarizedDark",
|
|
302
|
+
"solarizedLight",
|
|
303
|
+
"srcery",
|
|
304
|
+
"stackoverflowDark",
|
|
305
|
+
"stackoverflowLight",
|
|
306
|
+
"sunburst",
|
|
307
|
+
"tomorrowNightBlue",
|
|
308
|
+
"tomorrowNightBright",
|
|
309
|
+
"tomorrowNightEighties",
|
|
310
|
+
"tomorrowNight",
|
|
311
|
+
"tomorrow",
|
|
312
|
+
"vs",
|
|
313
|
+
"vs2015",
|
|
314
|
+
"xcode",
|
|
315
|
+
"xt256",
|
|
316
|
+
"zenburn"
|
|
317
|
+
];
|
|
190
318
|
export {
|
|
191
319
|
prismStyleNames,
|
|
320
|
+
hljsStyleNames,
|
|
192
321
|
MarkdownComponent
|
|
193
322
|
};
|
|
194
|
-
|
|
195
|
-
//# debugId=06022BF521D3780764756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codearcade/markdown",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dist/*.css"
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "bun ./builder.ts && bun run generate-types",
|
|
27
|
+
"build": "NODE_ENV=production && bun ./builder.ts && bun run generate-types",
|
|
28
28
|
"prepublishOnly": "bun run build",
|
|
29
29
|
"generate-types": "bunx tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
30
30
|
"clear": "rm -rf dist"
|
package/dist/index.js.map
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
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
|
-
}
|