@codearcade/markdown 1.0.2 → 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/constants/theme.d.ts +2 -2
- package/dist/index.js +15 -15
- package/package.json +2 -2
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,6 +1,6 @@
|
|
|
1
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
|
-
|
|
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
3
|
type PrismTheme = (typeof prismStyleNames)[number];
|
|
4
4
|
type HljsTheme = (typeof hljsStyleNames)[number];
|
|
5
|
-
export { prismStyleNames };
|
|
5
|
+
export { prismStyleNames, hljsStyleNames };
|
|
6
6
|
export type { PrismTheme, HljsTheme };
|
package/dist/index.js
CHANGED
|
@@ -21,12 +21,12 @@ var markdown_module_default = {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
// src/components/icons.tsx
|
|
24
|
-
import {
|
|
24
|
+
import { jsx } from "react/jsx-runtime";
|
|
25
25
|
var CheckMarkIcon = () => {
|
|
26
|
-
return /* @__PURE__ */
|
|
26
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
27
27
|
xmlns: "http://www.w3.org/2000/svg",
|
|
28
28
|
viewBox: "0 0 512 512",
|
|
29
|
-
children: /* @__PURE__ */
|
|
29
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
30
30
|
fill: "none",
|
|
31
31
|
stroke: "currentColor",
|
|
32
32
|
"stroke-linecap": "round",
|
|
@@ -37,11 +37,11 @@ var CheckMarkIcon = () => {
|
|
|
37
37
|
}, undefined, false, undefined, this);
|
|
38
38
|
};
|
|
39
39
|
var CopyIcon = () => {
|
|
40
|
-
return /* @__PURE__ */
|
|
40
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
41
41
|
xmlns: "http://www.w3.org/2000/svg",
|
|
42
42
|
viewBox: "0 0 512 512",
|
|
43
43
|
children: [
|
|
44
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ jsx("rect", {
|
|
45
45
|
x: "128",
|
|
46
46
|
y: "128",
|
|
47
47
|
width: "336",
|
|
@@ -53,7 +53,7 @@ var CopyIcon = () => {
|
|
|
53
53
|
"stroke-linejoin": "round",
|
|
54
54
|
"stroke-width": "24"
|
|
55
55
|
}, undefined, false, undefined, this),
|
|
56
|
-
/* @__PURE__ */
|
|
56
|
+
/* @__PURE__ */ jsx("path", {
|
|
57
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",
|
|
58
58
|
fill: "none",
|
|
59
59
|
stroke: "currentColor",
|
|
@@ -66,7 +66,7 @@ var CopyIcon = () => {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
// src/components/markdown.tsx
|
|
69
|
-
import {
|
|
69
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
70
70
|
"use client";
|
|
71
71
|
var CopyToClipboard = ({ text }) => {
|
|
72
72
|
const [isCopied, setIsCopied] = useState(false);
|
|
@@ -84,12 +84,12 @@ var CopyToClipboard = ({ text }) => {
|
|
|
84
84
|
}, 2000);
|
|
85
85
|
}
|
|
86
86
|
}, [text, isCopied]);
|
|
87
|
-
return /* @__PURE__ */
|
|
87
|
+
return /* @__PURE__ */ jsx2("button", {
|
|
88
88
|
onClick: copyToClipboard,
|
|
89
89
|
className: markdown_module_default.markdownAction,
|
|
90
90
|
"aria-label": isCopied ? "Copied to clipboard" : "Copy to clipboard",
|
|
91
91
|
children: [
|
|
92
|
-
isCopied ? /* @__PURE__ */
|
|
92
|
+
isCopied ? /* @__PURE__ */ jsx2(CheckMarkIcon, {}, undefined, false, undefined, this) : /* @__PURE__ */ jsx2(CopyIcon, {}, undefined, false, undefined, this),
|
|
93
93
|
" ",
|
|
94
94
|
isCopied ? "Copied" : "Copy"
|
|
95
95
|
]
|
|
@@ -134,19 +134,19 @@ var MarkdownComponent = (props) => {
|
|
|
134
134
|
isMounted = false;
|
|
135
135
|
};
|
|
136
136
|
}, [engine, theme]);
|
|
137
|
-
return /* @__PURE__ */
|
|
137
|
+
return /* @__PURE__ */ jsx2("section", {
|
|
138
138
|
className: `${markdown_module_default.markdownBody} ${theme}`,
|
|
139
|
-
children: /* @__PURE__ */
|
|
139
|
+
children: /* @__PURE__ */ jsx2(ReactMarkdown, {
|
|
140
140
|
remarkPlugins: [remarkGfm],
|
|
141
141
|
components: {
|
|
142
142
|
code(props2) {
|
|
143
143
|
const { className, children, ref, ...rest } = props2;
|
|
144
144
|
const match = /language-(\w+)/.exec(className || "");
|
|
145
145
|
const codeText = String(children).replace(/\n$/, "");
|
|
146
|
-
return match && Highlighter ? /* @__PURE__ */
|
|
146
|
+
return match && Highlighter ? /* @__PURE__ */ jsx2("div", {
|
|
147
147
|
style: { position: "relative" },
|
|
148
148
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ jsx2(Highlighter, {
|
|
150
150
|
...rest,
|
|
151
151
|
PreTag: "div",
|
|
152
152
|
ref,
|
|
@@ -155,11 +155,11 @@ var MarkdownComponent = (props) => {
|
|
|
155
155
|
style: markdownTheme,
|
|
156
156
|
children: codeText
|
|
157
157
|
}, undefined, false, undefined, this),
|
|
158
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ jsx2(CopyToClipboard, {
|
|
159
159
|
text: codeText
|
|
160
160
|
}, undefined, false, undefined, this)
|
|
161
161
|
]
|
|
162
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
162
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx2("code", {
|
|
163
163
|
...rest,
|
|
164
164
|
className,
|
|
165
165
|
children
|
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"
|