@infinilabs/markdown 0.0.1
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 +111 -0
- package/dist/index.d.ts +11 -0
- package/dist/markdown.js +85 -0
- package/dist/markdown.umd.cjs +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# @infinilabs/markdown
|
|
2
|
+
|
|
3
|
+
A powerful and flexible Markdown component for React applications, built on top of `@ant-design/x-markdown`. It supports rendering markdown content from strings or URLs, with syntax highlighting, tables, and customizable components.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @infinilabs/markdown antd react react-dom
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @infinilabs/markdown antd react react-dom
|
|
11
|
+
# or
|
|
12
|
+
yarn add @infinilabs/markdown antd react react-dom
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Basic Usage
|
|
18
|
+
|
|
19
|
+
Render markdown content directly:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import Markdown from '@infinilabs/markdown';
|
|
23
|
+
|
|
24
|
+
const markdownContent = `
|
|
25
|
+
# Hello World
|
|
26
|
+
|
|
27
|
+
This is a markdown component.
|
|
28
|
+
|
|
29
|
+
- Item 1
|
|
30
|
+
- Item 2
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
function App() {
|
|
34
|
+
return (
|
|
35
|
+
<Markdown content={markdownContent} />
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Fetch from URL
|
|
41
|
+
|
|
42
|
+
Fetch and render markdown from a URL:
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import Markdown from '@infinilabs/markdown';
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
return (
|
|
49
|
+
<Markdown url="https://raw.githubusercontent.com/infinilabs/ui-common/main/README.md" />
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### With Custom Styles
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import Markdown from '@infinilabs/markdown';
|
|
58
|
+
|
|
59
|
+
function App() {
|
|
60
|
+
return (
|
|
61
|
+
<Markdown
|
|
62
|
+
content="# Styled Content"
|
|
63
|
+
className="custom-markdown-class"
|
|
64
|
+
style={{ padding: 20 }}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## API Reference
|
|
71
|
+
|
|
72
|
+
### Markdown
|
|
73
|
+
|
|
74
|
+
The `Markdown` component accepts all props from `XMarkdownProps` (from `@ant-design/x-markdown`) plus the following additional props:
|
|
75
|
+
|
|
76
|
+
| Property | Type | Default | Description |
|
|
77
|
+
| --- | --- | --- | --- |
|
|
78
|
+
| `content` | `string` | - | The markdown content string to render. |
|
|
79
|
+
| `url` | `string` | - | The URL to fetch markdown content from. If provided, it overrides `content` after fetching. |
|
|
80
|
+
| `className` | `string` | - | Custom CSS class name. |
|
|
81
|
+
| `style` | `CSSProperties` | - | Custom inline styles. |
|
|
82
|
+
| `components` | `Components` | - | Map of custom components to override default markdown elements (e.g., `code`, `a`, `table`). |
|
|
83
|
+
|
|
84
|
+
### Supported Syntax
|
|
85
|
+
|
|
86
|
+
- Headers (H1-H6)
|
|
87
|
+
- Lists (Ordered and Unordered)
|
|
88
|
+
- Links
|
|
89
|
+
- Images
|
|
90
|
+
- Tables
|
|
91
|
+
- Code Blocks (with syntax highlighting)
|
|
92
|
+
- Blockquotes
|
|
93
|
+
- Inline Code
|
|
94
|
+
- Emphasis (Bold, Italic)
|
|
95
|
+
|
|
96
|
+
## Development
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Install dependencies
|
|
100
|
+
pnpm install
|
|
101
|
+
|
|
102
|
+
# Start development server
|
|
103
|
+
pnpm dev
|
|
104
|
+
|
|
105
|
+
# Build for production
|
|
106
|
+
pnpm build
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as u } from "react/jsx-runtime";
|
|
2
|
+
import { XMarkdown as b } from "@ant-design/x-markdown";
|
|
3
|
+
import g from "clsx";
|
|
4
|
+
import { Children as p, isValidElement as f, useState as w, useEffect as x } from "react";
|
|
5
|
+
import { Typography as A, Table as T } from "antd";
|
|
6
|
+
import { Mermaid as _, CodeHighlighter as C } from "@ant-design/x";
|
|
7
|
+
const { Text: k } = A, N = (t) => {
|
|
8
|
+
const { className: o, children: r } = t, n = o?.match(/language-(\w+)/)?.[1] ?? "";
|
|
9
|
+
return typeof r != "string" ? null : n === "mermaid" ? /* @__PURE__ */ u(_, { children: r }) : n ? /* @__PURE__ */ u(C, { lang: n, children: r }) : /* @__PURE__ */ u(k, { code: !0, children: r });
|
|
10
|
+
}, m = (t) => typeof t == "string" || typeof t == "number" ? String(t) : f(t) ? m(t.props.children) : Array.isArray(t) ? t.map(m).join("") : "", $ = (t) => {
|
|
11
|
+
const o = [], r = [], n = p.toArray(t);
|
|
12
|
+
for (const e of n) {
|
|
13
|
+
if (!f(e)) continue;
|
|
14
|
+
const d = e.type;
|
|
15
|
+
if (d === "thead") {
|
|
16
|
+
const a = p.toArray(e.props.children);
|
|
17
|
+
for (const c of a) {
|
|
18
|
+
if (!f(c)) continue;
|
|
19
|
+
const i = p.toArray(c.props.children);
|
|
20
|
+
let s = 0;
|
|
21
|
+
for (const l of i) {
|
|
22
|
+
if (!f(l)) continue;
|
|
23
|
+
const h = m(l.props.children);
|
|
24
|
+
o.push({
|
|
25
|
+
title: h,
|
|
26
|
+
dataIndex: `col_${s}`,
|
|
27
|
+
key: `col_${s}`
|
|
28
|
+
}), s++;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (d === "tbody") {
|
|
33
|
+
const a = p.toArray(e.props.children);
|
|
34
|
+
let c = 0;
|
|
35
|
+
for (const i of a) {
|
|
36
|
+
if (!f(i)) continue;
|
|
37
|
+
const s = { key: `row_${c}` }, l = p.toArray(i.props.children);
|
|
38
|
+
let h = 0;
|
|
39
|
+
for (const y of l)
|
|
40
|
+
f(y) && (s[`col_${h}`] = y.props.children, h++);
|
|
41
|
+
r.push(s), c++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { columns: o, dataSource: r };
|
|
46
|
+
}, S = ({ children: t }) => {
|
|
47
|
+
const { columns: o, dataSource: r } = $(t);
|
|
48
|
+
return /* @__PURE__ */ u(
|
|
49
|
+
T,
|
|
50
|
+
{
|
|
51
|
+
className: "[&_table]:w-full! [&_table]:table!",
|
|
52
|
+
columns: o,
|
|
53
|
+
dataSource: r,
|
|
54
|
+
pagination: !1,
|
|
55
|
+
size: "small",
|
|
56
|
+
bordered: !0
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}, { Link: I } = A, L = (t) => {
|
|
60
|
+
const { url: o, className: r, components: n, ...e } = t, [d, a] = w(e.content), c = async (i) => {
|
|
61
|
+
const l = await (await fetch(i)).text();
|
|
62
|
+
a(l);
|
|
63
|
+
};
|
|
64
|
+
return x(() => {
|
|
65
|
+
o && c(o);
|
|
66
|
+
}, [o]), x(() => {
|
|
67
|
+
a(e.content);
|
|
68
|
+
}, [e.content]), /* @__PURE__ */ u(
|
|
69
|
+
b,
|
|
70
|
+
{
|
|
71
|
+
...e,
|
|
72
|
+
className: g("[&_h1,h2,h3,h4,h5,h6,ul,ol,p]:[all:revert]", r),
|
|
73
|
+
content: d,
|
|
74
|
+
components: {
|
|
75
|
+
code: N,
|
|
76
|
+
a: I,
|
|
77
|
+
table: S,
|
|
78
|
+
...n
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
export {
|
|
84
|
+
L as default
|
|
85
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(e,f){typeof exports=="object"&&typeof module<"u"?module.exports=f(require("react/jsx-runtime"),require("@ant-design/x-markdown"),require("clsx"),require("react"),require("antd"),require("@ant-design/x")):typeof define=="function"&&define.amd?define(["react/jsx-runtime","@ant-design/x-markdown","clsx","react","antd","@ant-design/x"],f):(e=typeof globalThis<"u"?globalThis:e||self,e.InfinilabsMarkdown=f(e.jsxRuntime,e.AntDesignXMarkdown,e.clsx,e.React,e.antd,e.AntDesignX))})(this,(function(e,f,A,t,m,x){"use strict";const{Text:g}=m.Typography,k=n=>{const{className:o,children:r}=n,i=o?.match(/language-(\w+)/)?.[1]??"";return typeof r!="string"?null:i==="mermaid"?e.jsx(x.Mermaid,{children:r}):i?e.jsx(x.CodeHighlighter,{lang:i,children:r}):e.jsx(g,{code:!0,children:r})},y=n=>typeof n=="string"||typeof n=="number"?String(n):t.isValidElement(n)?y(n.props.children):Array.isArray(n)?n.map(y).join(""):"",C=n=>{const o=[],r=[],i=t.Children.toArray(n);for(const s of i){if(!t.isValidElement(s))continue;const p=s.type;if(p==="thead"){const l=t.Children.toArray(s.props.children);for(const c of l){if(!t.isValidElement(c))continue;const d=t.Children.toArray(c.props.children);let a=0;for(const u of d){if(!t.isValidElement(u))continue;const h=y(u.props.children);o.push({title:h,dataIndex:`col_${a}`,key:`col_${a}`}),a++}}}if(p==="tbody"){const l=t.Children.toArray(s.props.children);let c=0;for(const d of l){if(!t.isValidElement(d))continue;const a={key:`row_${c}`},u=t.Children.toArray(d.props.children);let h=0;for(const w of u)t.isValidElement(w)&&(a[`col_${h}`]=w.props.children,h++);r.push(a),c++}}}return{columns:o,dataSource:r}},T=({children:n})=>{const{columns:o,dataSource:r}=C(n);return e.jsx(m.Table,{className:"[&_table]:w-full! [&_table]:table!",columns:o,dataSource:r,pagination:!1,size:"small",bordered:!0})},{Link:E}=m.Typography;return n=>{const{url:o,className:r,components:i,...s}=n,[p,l]=t.useState(s.content),c=async d=>{const u=await(await fetch(d)).text();l(u)};return t.useEffect(()=>{o&&c(o)},[o]),t.useEffect(()=>{l(s.content)},[s.content]),e.jsx(f.XMarkdown,{...s,className:A("[&_h1,h2,h3,h4,h5,h6,ul,ol,p]:[all:revert]",r),content:p,components:{code:k,a:E,table:T,...i}})}}));
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@infinilabs/markdown",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/markdown.umd.cjs",
|
|
10
|
+
"module": "./dist/markdown.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/markdown.js",
|
|
16
|
+
"require": "./dist/markdown.umd.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"dev": "vite",
|
|
24
|
+
"build": "tsc -b && vite build",
|
|
25
|
+
"preview": "vite preview"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@ant-design/x": "^2.1.3",
|
|
29
|
+
"@ant-design/x-markdown": "^2.1.3",
|
|
30
|
+
"clsx": "^2.1.1"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"antd": ">=5",
|
|
34
|
+
"react": ">=18",
|
|
35
|
+
"react-dom": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^24.10.1",
|
|
39
|
+
"@types/react": "^19.2.5",
|
|
40
|
+
"@types/react-dom": "^19.2.3",
|
|
41
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
42
|
+
"globals": "^16.5.0",
|
|
43
|
+
"typescript": "~5.8.2",
|
|
44
|
+
"unocss": "^66.5.10",
|
|
45
|
+
"vite": "^7.2.4",
|
|
46
|
+
"vite-plugin-css-injected-by-js": "^3.5.2",
|
|
47
|
+
"vite-plugin-dts": "^4.5.4"
|
|
48
|
+
}
|
|
49
|
+
}
|