@haklex/rich-renderer-codeblock 0.0.3 → 0.0.5
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/dist/CodeBlockCard.d.ts.map +1 -1
- package/dist/CodeBlockEditRenderer.d.ts.map +1 -1
- package/dist/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/constants.mjs +76 -0
- package/dist/icons/file.d.ts +13 -0
- package/dist/icons/file.d.ts.map +1 -0
- package/dist/icons/index.d.ts +5 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/language.d.ts +11 -0
- package/dist/icons/language.d.ts.map +1 -0
- package/dist/icons/material-icon.d.ts +3 -0
- package/dist/icons/material-icon.d.ts.map +1 -0
- package/dist/icons.mjs +96 -0
- package/dist/index.mjs +80 -138
- package/dist/language-AfAZN4lZ.js +131 -0
- package/dist/rich-renderer-codeblock.css +89 -39
- package/dist/shiki.mjs +33 -0
- package/dist/styles.css.d.ts +39 -1
- package/dist/styles.css.d.ts.map +1 -1
- package/package.json +10 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockCard.d.ts","sourceRoot":"","sources":["../src/CodeBlockCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CodeBlockCard.d.ts","sourceRoot":"","sources":["../src/CodeBlockCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAerD,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,kBAAkB,2CAuGpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockEditRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockEditRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"CodeBlockEditRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockEditRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAQ1C,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,sBAAsB,CAmLvE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAQ1C,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,sBAAsB,CAgEnE,CAAA;AAED,eAAe,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const languageToIconMap = {
|
|
2
|
+
javascript: "JS",
|
|
3
|
+
js: "JS",
|
|
4
|
+
typescript: "TS",
|
|
5
|
+
ts: "TS",
|
|
6
|
+
jsx: "JSX",
|
|
7
|
+
tsx: "TSX",
|
|
8
|
+
html: "HTML",
|
|
9
|
+
css: "CSS",
|
|
10
|
+
scss: "SCSS",
|
|
11
|
+
json: "JSON",
|
|
12
|
+
markdown: "MD",
|
|
13
|
+
md: "MD",
|
|
14
|
+
bash: "SH",
|
|
15
|
+
sh: "SH",
|
|
16
|
+
shell: "SH",
|
|
17
|
+
zsh: "SH",
|
|
18
|
+
python: "PY",
|
|
19
|
+
py: "PY",
|
|
20
|
+
rust: "RS",
|
|
21
|
+
go: "GO",
|
|
22
|
+
java: "JAVA",
|
|
23
|
+
c: "C",
|
|
24
|
+
cpp: "C++",
|
|
25
|
+
"c++": "C++",
|
|
26
|
+
swift: "SW",
|
|
27
|
+
kotlin: "KT",
|
|
28
|
+
yaml: "YAML",
|
|
29
|
+
yml: "YAML",
|
|
30
|
+
sql: "SQL"
|
|
31
|
+
};
|
|
32
|
+
const languageToColorMap = {
|
|
33
|
+
javascript: "#f7df1e",
|
|
34
|
+
js: "#f7df1e",
|
|
35
|
+
typescript: "#3178c6",
|
|
36
|
+
ts: "#3178c6",
|
|
37
|
+
jsx: "#61dafb",
|
|
38
|
+
tsx: "#61dafb",
|
|
39
|
+
html: "#e34f26",
|
|
40
|
+
css: "#1572b6",
|
|
41
|
+
scss: "#cc6699",
|
|
42
|
+
json: "#f59e0b",
|
|
43
|
+
markdown: "#737373",
|
|
44
|
+
md: "#737373",
|
|
45
|
+
bash: "#4eaa25",
|
|
46
|
+
sh: "#4eaa25",
|
|
47
|
+
shell: "#4eaa25",
|
|
48
|
+
zsh: "#4eaa25",
|
|
49
|
+
python: "#3776ab",
|
|
50
|
+
py: "#3776ab",
|
|
51
|
+
rust: "#dea584",
|
|
52
|
+
go: "#00add8",
|
|
53
|
+
java: "#b07219",
|
|
54
|
+
c: "#a8b9cc",
|
|
55
|
+
cpp: "#00599c",
|
|
56
|
+
"c++": "#00599c",
|
|
57
|
+
swift: "#fa7343",
|
|
58
|
+
kotlin: "#7f52ff",
|
|
59
|
+
yaml: "#cb171e",
|
|
60
|
+
yml: "#cb171e",
|
|
61
|
+
sql: "#e38c00"
|
|
62
|
+
};
|
|
63
|
+
function normalizeLanguage(lang) {
|
|
64
|
+
if (!lang) return "text";
|
|
65
|
+
return lang.trim().toLowerCase() || "text";
|
|
66
|
+
}
|
|
67
|
+
function getLanguageDisplayName(lang) {
|
|
68
|
+
if (lang === "text") return "TEXT";
|
|
69
|
+
return lang.toUpperCase();
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
getLanguageDisplayName,
|
|
73
|
+
languageToColorMap,
|
|
74
|
+
languageToIconMap,
|
|
75
|
+
normalizeLanguage
|
|
76
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
/** Maps file extension to material-icon-theme icon name. */
|
|
3
|
+
export declare const EXT_TO_ICON: Record<string, string>;
|
|
4
|
+
export interface FileIconProps {
|
|
5
|
+
filename: string;
|
|
6
|
+
size?: number;
|
|
7
|
+
/** Optional class for the wrapper (e.g. consumer styles). */
|
|
8
|
+
className?: string;
|
|
9
|
+
/** Fallback when no icon is found. Default "F". */
|
|
10
|
+
fallback?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export declare const FileIcon: FC<FileIconProps>;
|
|
13
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/icons/file.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK1C,4DAA4D;AAC5D,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkD9C,CAAA;AAQD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAiCtC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/icons/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAC,YAAY,EAAE,MAAM,YAAY,CAAA;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
/** Maps normalized language to material-icon-theme icon name. */
|
|
3
|
+
export declare const LANG_TO_ICON: Record<string, string>;
|
|
4
|
+
/** Returns whether a Material icon is available for the given language. */
|
|
5
|
+
export declare function hasLanguageIcon(lang: string): boolean;
|
|
6
|
+
export declare const LanguageIcon: FC<{
|
|
7
|
+
language: string;
|
|
8
|
+
size?: number;
|
|
9
|
+
className?: string;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/icons/language.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAM/B,iEAAiE;AACjE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA8C/C,CAAA;AAOD,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAiCA,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material-icon.d.ts","sourceRoot":"","sources":["../../src/icons/material-icon.ts"],"names":[],"mappings":"AAGA,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKlE"}
|
package/dist/icons.mjs
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { n as getMaterialIconSvg } from "./language-AfAZN4lZ.js";
|
|
4
|
+
import { o, L, h } from "./language-AfAZN4lZ.js";
|
|
5
|
+
const EXT_TO_ICON = {
|
|
6
|
+
ts: "typescript",
|
|
7
|
+
tsx: "react-ts",
|
|
8
|
+
// TSX → React icon (same as JSX)
|
|
9
|
+
mts: "typescript",
|
|
10
|
+
cts: "typescript",
|
|
11
|
+
js: "javascript",
|
|
12
|
+
jsx: "react",
|
|
13
|
+
mjs: "javascript",
|
|
14
|
+
cjs: "javascript",
|
|
15
|
+
py: "python",
|
|
16
|
+
rs: "rust",
|
|
17
|
+
go: "go",
|
|
18
|
+
java: "java",
|
|
19
|
+
html: "html",
|
|
20
|
+
htm: "html",
|
|
21
|
+
css: "css",
|
|
22
|
+
scss: "sass",
|
|
23
|
+
sass: "sass",
|
|
24
|
+
less: "sass",
|
|
25
|
+
json: "json",
|
|
26
|
+
jsonc: "json",
|
|
27
|
+
json5: "json",
|
|
28
|
+
md: "markdown",
|
|
29
|
+
mdx: "markdown",
|
|
30
|
+
sh: "console",
|
|
31
|
+
bash: "console",
|
|
32
|
+
zsh: "console",
|
|
33
|
+
yml: "yaml",
|
|
34
|
+
yaml: "yaml",
|
|
35
|
+
sql: "database",
|
|
36
|
+
c: "c",
|
|
37
|
+
h: "c",
|
|
38
|
+
cpp: "cpp",
|
|
39
|
+
cc: "cpp",
|
|
40
|
+
cxx: "cpp",
|
|
41
|
+
hpp: "cpp",
|
|
42
|
+
swift: "swift",
|
|
43
|
+
kt: "kotlin",
|
|
44
|
+
kts: "kotlin",
|
|
45
|
+
rb: "ruby",
|
|
46
|
+
php: "php",
|
|
47
|
+
vue: "vue",
|
|
48
|
+
svelte: "svelte",
|
|
49
|
+
toml: "toml",
|
|
50
|
+
xml: "xml",
|
|
51
|
+
graphql: "graphql",
|
|
52
|
+
gql: "graphql",
|
|
53
|
+
dockerfile: "docker",
|
|
54
|
+
lua: "lua",
|
|
55
|
+
zig: "zig"
|
|
56
|
+
};
|
|
57
|
+
function getFileIconSvg(filename) {
|
|
58
|
+
const ext = filename.split(".").pop()?.toLowerCase() ?? "";
|
|
59
|
+
const iconName = EXT_TO_ICON[ext] ?? "file";
|
|
60
|
+
return getMaterialIconSvg(iconName);
|
|
61
|
+
}
|
|
62
|
+
const FileIcon = ({
|
|
63
|
+
filename,
|
|
64
|
+
size = 16,
|
|
65
|
+
className,
|
|
66
|
+
fallback = "F"
|
|
67
|
+
}) => {
|
|
68
|
+
const html = useMemo(() => getFileIconSvg(filename), [filename]);
|
|
69
|
+
const wrapperStyle = {
|
|
70
|
+
width: size,
|
|
71
|
+
height: size,
|
|
72
|
+
display: "inline-flex",
|
|
73
|
+
alignItems: "center",
|
|
74
|
+
justifyContent: "center",
|
|
75
|
+
opacity: html ? 1 : 0.5,
|
|
76
|
+
fontSize: size * 0.6
|
|
77
|
+
};
|
|
78
|
+
if (!html) {
|
|
79
|
+
return /* @__PURE__ */ jsx("span", { className, style: wrapperStyle, children: fallback });
|
|
80
|
+
}
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
"span",
|
|
83
|
+
{
|
|
84
|
+
className,
|
|
85
|
+
style: { width: size, height: size },
|
|
86
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
export {
|
|
91
|
+
FileIcon,
|
|
92
|
+
o as LANG_TO_ICON,
|
|
93
|
+
L as LanguageIcon,
|
|
94
|
+
getMaterialIconSvg,
|
|
95
|
+
h as hasLanguageIcon
|
|
96
|
+
};
|
package/dist/index.mjs
CHANGED
|
@@ -2,76 +2,11 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useColorScheme } from "@haklex/rich-editor";
|
|
3
3
|
import { useState, useRef, useEffect, useCallback, useMemo } from "react";
|
|
4
4
|
import { Check, Copy, ChevronDown } from "lucide-react";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
jsx: "JSX",
|
|
11
|
-
tsx: "TSX",
|
|
12
|
-
html: "HTML",
|
|
13
|
-
css: "CSS",
|
|
14
|
-
scss: "SCSS",
|
|
15
|
-
json: "JSON",
|
|
16
|
-
markdown: "MD",
|
|
17
|
-
md: "MD",
|
|
18
|
-
bash: "SH",
|
|
19
|
-
sh: "SH",
|
|
20
|
-
shell: "SH",
|
|
21
|
-
zsh: "SH",
|
|
22
|
-
python: "PY",
|
|
23
|
-
py: "PY",
|
|
24
|
-
rust: "RS",
|
|
25
|
-
go: "GO",
|
|
26
|
-
java: "JAVA",
|
|
27
|
-
c: "C",
|
|
28
|
-
cpp: "C++",
|
|
29
|
-
"c++": "C++",
|
|
30
|
-
swift: "SW",
|
|
31
|
-
kotlin: "KT",
|
|
32
|
-
yaml: "YAML",
|
|
33
|
-
yml: "YAML",
|
|
34
|
-
sql: "SQL"
|
|
35
|
-
};
|
|
36
|
-
const languageToColorMap = {
|
|
37
|
-
javascript: "#f7df1e",
|
|
38
|
-
js: "#f7df1e",
|
|
39
|
-
typescript: "#3178c6",
|
|
40
|
-
ts: "#3178c6",
|
|
41
|
-
jsx: "#61dafb",
|
|
42
|
-
tsx: "#61dafb",
|
|
43
|
-
html: "#e34f26",
|
|
44
|
-
css: "#1572b6",
|
|
45
|
-
scss: "#cc6699",
|
|
46
|
-
json: "#f59e0b",
|
|
47
|
-
markdown: "#737373",
|
|
48
|
-
md: "#737373",
|
|
49
|
-
bash: "#4eaa25",
|
|
50
|
-
sh: "#4eaa25",
|
|
51
|
-
shell: "#4eaa25",
|
|
52
|
-
zsh: "#4eaa25",
|
|
53
|
-
python: "#3776ab",
|
|
54
|
-
py: "#3776ab",
|
|
55
|
-
rust: "#dea584",
|
|
56
|
-
go: "#00add8",
|
|
57
|
-
java: "#b07219",
|
|
58
|
-
c: "#a8b9cc",
|
|
59
|
-
cpp: "#00599c",
|
|
60
|
-
"c++": "#00599c",
|
|
61
|
-
swift: "#fa7343",
|
|
62
|
-
kotlin: "#7f52ff",
|
|
63
|
-
yaml: "#cb171e",
|
|
64
|
-
yml: "#cb171e",
|
|
65
|
-
sql: "#e38c00"
|
|
66
|
-
};
|
|
67
|
-
function normalizeLanguage(lang) {
|
|
68
|
-
if (!lang) return "text";
|
|
69
|
-
return lang.trim().toLowerCase() || "text";
|
|
70
|
-
}
|
|
71
|
-
function getLanguageDisplayName(lang) {
|
|
72
|
-
if (lang === "text") return "TEXT";
|
|
73
|
-
return lang.toUpperCase();
|
|
74
|
-
}
|
|
5
|
+
import { normalizeLanguage, getLanguageDisplayName, languageToColorMap } from "./constants.mjs";
|
|
6
|
+
import "@iconify/utils";
|
|
7
|
+
import "@iconify-json/material-icon-theme";
|
|
8
|
+
import { c as card, s as semanticClassNames, l as lang, h as hasLanguageIcon, L as LanguageIcon, a as copyButton, b as bodyBackground, e as expandWrap, d as expandButton, f as scroll, g as scrollCollapsed, i as lined, j as linedWithNumbers, k as body, m as bodyReadonly } from "./language-AfAZN4lZ.js";
|
|
9
|
+
import { getHighlighterWithLang, SHIKI_THEMES } from "./shiki.mjs";
|
|
75
10
|
const CopyIcon = /* @__PURE__ */ jsx(Copy, { size: 16 });
|
|
76
11
|
const CheckIcon = /* @__PURE__ */ jsx(Check, { size: 16 });
|
|
77
12
|
const ExpandIcon = /* @__PURE__ */ jsx(ChevronDown, { size: 14 });
|
|
@@ -107,7 +42,6 @@ function CodeBlockCard({
|
|
|
107
42
|
}).catch(() => {
|
|
108
43
|
});
|
|
109
44
|
}, [code]);
|
|
110
|
-
const languageIcon = languageToIconMap[normalizedLanguage] || "";
|
|
111
45
|
const languageLabel = getLanguageDisplayName(normalizedLanguage);
|
|
112
46
|
const accent = languageToColorMap[normalizedLanguage] || "#737373";
|
|
113
47
|
const cardStyle = useMemo(
|
|
@@ -115,67 +49,66 @@ function CodeBlockCard({
|
|
|
115
49
|
[accent]
|
|
116
50
|
);
|
|
117
51
|
const scrollClassName = [
|
|
118
|
-
|
|
119
|
-
|
|
52
|
+
scroll,
|
|
53
|
+
semanticClassNames.scroll,
|
|
54
|
+
isCollapsed && isOverflow && scrollCollapsed,
|
|
55
|
+
isCollapsed && isOverflow && semanticClassNames.scrollCollapsed
|
|
120
56
|
].filter(Boolean).join(" ");
|
|
121
|
-
return /* @__PURE__ */ jsxs(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
57
|
+
return /* @__PURE__ */ jsxs(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
className: `${card} ${semanticClassNames.card}`,
|
|
61
|
+
style: cardStyle,
|
|
62
|
+
children: [
|
|
63
|
+
normalizedLanguage !== "text" && /* @__PURE__ */ jsx(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: `${lang} ${semanticClassNames.lang}`,
|
|
67
|
+
"aria-hidden": true,
|
|
68
|
+
children: hasLanguageIcon(normalizedLanguage) ? /* @__PURE__ */ jsx(LanguageIcon, { language: normalizedLanguage, size: 14 }) : /* @__PURE__ */ jsx("span", { children: languageLabel })
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
className: `${copyButton} ${semanticClassNames.copyButton}`,
|
|
76
|
+
onClick: handleCopy,
|
|
77
|
+
"aria-label": copied ? "Copied" : "Copy code",
|
|
78
|
+
children: copied ? CheckIcon : CopyIcon
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
/* @__PURE__ */ jsxs(
|
|
82
|
+
"div",
|
|
83
|
+
{
|
|
84
|
+
className: `${bodyBackground} ${semanticClassNames.bodyBackground}`,
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ jsx("div", { ref: scrollRef, className: scrollClassName, children }),
|
|
87
|
+
isOverflow && isCollapsed && /* @__PURE__ */ jsx(
|
|
88
|
+
"div",
|
|
89
|
+
{
|
|
90
|
+
className: `${expandWrap} ${semanticClassNames.expandWrap}`,
|
|
91
|
+
children: /* @__PURE__ */ jsxs(
|
|
92
|
+
"button",
|
|
93
|
+
{
|
|
94
|
+
type: "button",
|
|
95
|
+
className: `${expandButton} ${semanticClassNames.expandButton}`,
|
|
96
|
+
onClick: () => setIsCollapsed(false),
|
|
97
|
+
children: [
|
|
98
|
+
ExpandIcon,
|
|
99
|
+
/* @__PURE__ */ jsx("span", { children: "展开" })
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
]
|
|
171
109
|
}
|
|
172
|
-
|
|
173
|
-
return highlighter;
|
|
110
|
+
);
|
|
174
111
|
}
|
|
175
|
-
const SHIKI_THEMES = {
|
|
176
|
-
light: "github-light",
|
|
177
|
-
dark: "github-dark"
|
|
178
|
-
};
|
|
179
112
|
const CodeBlockEditRenderer = ({
|
|
180
113
|
code,
|
|
181
114
|
language,
|
|
@@ -218,13 +151,13 @@ const CodeBlockEditRenderer = ({
|
|
|
218
151
|
if (disposed) return;
|
|
219
152
|
const theme = SHIKI_THEMES[props.colorScheme];
|
|
220
153
|
const loaded2 = highlighter.getLoadedLanguages();
|
|
221
|
-
const
|
|
154
|
+
const lang2 = loaded2.includes(props.normalizedLanguage) ? props.normalizedLanguage : "text";
|
|
222
155
|
const editor = shikiCode().withOptions({
|
|
223
156
|
readOnly: !props.editable,
|
|
224
157
|
lineNumbers: props.showLineNumbers ? "on" : "off"
|
|
225
158
|
}).create(container, highlighter, {
|
|
226
159
|
value: props.code,
|
|
227
|
-
language:
|
|
160
|
+
language: lang2,
|
|
228
161
|
theme
|
|
229
162
|
});
|
|
230
163
|
if (!props.editable) {
|
|
@@ -277,10 +210,17 @@ const CodeBlockEditRenderer = ({
|
|
|
277
210
|
}, [code, normalizedLanguage, colorScheme, showLineNumbers, editable]);
|
|
278
211
|
const fallbackLines = useMemo(() => code.split("\n"), [code]);
|
|
279
212
|
const fallbackClassName = [
|
|
280
|
-
|
|
281
|
-
|
|
213
|
+
lined,
|
|
214
|
+
semanticClassNames.lined,
|
|
215
|
+
showLineNumbers && linedWithNumbers,
|
|
216
|
+
showLineNumbers && semanticClassNames.linedWithNumbers
|
|
217
|
+
].filter(Boolean).join(" ");
|
|
218
|
+
const bodyClassName = [
|
|
219
|
+
body,
|
|
220
|
+
semanticClassNames.body,
|
|
221
|
+
!editable && bodyReadonly,
|
|
222
|
+
!editable && semanticClassNames.bodyReadonly
|
|
282
223
|
].filter(Boolean).join(" ");
|
|
283
|
-
const bodyClassName = ["rr-code-body", !editable && "rr-code-readonly"].filter(Boolean).join(" ");
|
|
284
224
|
return /* @__PURE__ */ jsxs(CodeBlockCard, { code, language, children: [
|
|
285
225
|
!loaded && /* @__PURE__ */ jsx("pre", { className: fallbackClassName, children: /* @__PURE__ */ jsx("code", { children: fallbackLines.map((line, i) => /* @__PURE__ */ jsx("span", { className: "line", children: line }, i)) }) }),
|
|
286
226
|
/* @__PURE__ */ jsx(
|
|
@@ -307,9 +247,9 @@ const CodeBlockRenderer = ({
|
|
|
307
247
|
const highlighter = await getHighlighterWithLang(normalizedLanguage);
|
|
308
248
|
if (cancelled) return;
|
|
309
249
|
const loaded = highlighter.getLoadedLanguages();
|
|
310
|
-
const
|
|
250
|
+
const lang2 = loaded.includes(normalizedLanguage) ? normalizedLanguage : "text";
|
|
311
251
|
const result = highlighter.codeToHtml(code, {
|
|
312
|
-
lang,
|
|
252
|
+
lang: lang2,
|
|
313
253
|
theme: SHIKI_THEMES[colorScheme]
|
|
314
254
|
});
|
|
315
255
|
if (!cancelled) setHtml(result);
|
|
@@ -320,8 +260,10 @@ const CodeBlockRenderer = ({
|
|
|
320
260
|
}, [code, normalizedLanguage, colorScheme]);
|
|
321
261
|
const fallbackLines = useMemo(() => code.split("\n"), [code]);
|
|
322
262
|
const linedClassName = [
|
|
323
|
-
|
|
324
|
-
|
|
263
|
+
lined,
|
|
264
|
+
semanticClassNames.lined,
|
|
265
|
+
showLineNumbers && linedWithNumbers,
|
|
266
|
+
showLineNumbers && semanticClassNames.linedWithNumbers
|
|
325
267
|
].filter(Boolean).join(" ");
|
|
326
268
|
return /* @__PURE__ */ jsx(CodeBlockCard, { code, language, children: html ? /* @__PURE__ */ jsx(
|
|
327
269
|
"div",
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { getIconData, iconToSVG, iconToHTML } from "@iconify/utils";
|
|
4
|
+
import { icons } from "@iconify-json/material-icon-theme";
|
|
5
|
+
function getMaterialIconSvg(iconName) {
|
|
6
|
+
const data = getIconData(icons, iconName);
|
|
7
|
+
if (!data) return null;
|
|
8
|
+
const svg = iconToSVG(data);
|
|
9
|
+
return iconToHTML(svg.body, svg.attributes);
|
|
10
|
+
}
|
|
11
|
+
var semanticClassNames = { card: "rr-code-card", lang: "rr-code-lang", langIcon: "rr-code-lang-icon", copyButton: "rr-code-copy", bodyBackground: "rr-code-bg", scroll: "rr-code-scroll", scrollCollapsed: "rr-code-scroll-collapsed", body: "rr-code-body", bodyReadonly: "rr-code-readonly", expandWrap: "rr-code-expand-wrap", expandButton: "rr-code-expand", lined: "rr-code-lined", linedWithNumbers: "rr-code-lined-ln" };
|
|
12
|
+
var card = "_1pn9r4q0";
|
|
13
|
+
var lang = "_1pn9r4q1";
|
|
14
|
+
var langIcon = "_1pn9r4q2";
|
|
15
|
+
var copyButton = "_1pn9r4q3";
|
|
16
|
+
var bodyBackground = "_1pn9r4q4";
|
|
17
|
+
var scroll = "_1pn9r4q5";
|
|
18
|
+
var scrollCollapsed = "_1pn9r4q6";
|
|
19
|
+
var body = "_1pn9r4q7";
|
|
20
|
+
var bodyReadonly = "_1pn9r4q8";
|
|
21
|
+
var expandWrap = "_1pn9r4q9";
|
|
22
|
+
var expandButton = "_1pn9r4qa";
|
|
23
|
+
var lined = "_1pn9r4qb";
|
|
24
|
+
var linedWithNumbers = "_1pn9r4qc";
|
|
25
|
+
const LANG_TO_ICON = {
|
|
26
|
+
javascript: "javascript",
|
|
27
|
+
js: "javascript",
|
|
28
|
+
typescript: "typescript",
|
|
29
|
+
ts: "typescript",
|
|
30
|
+
jsx: "react",
|
|
31
|
+
tsx: "react",
|
|
32
|
+
// TSX → React icon (same as JSX)
|
|
33
|
+
html: "html",
|
|
34
|
+
css: "css",
|
|
35
|
+
scss: "sass",
|
|
36
|
+
sass: "sass",
|
|
37
|
+
less: "sass",
|
|
38
|
+
json: "json",
|
|
39
|
+
jsonc: "json",
|
|
40
|
+
markdown: "markdown",
|
|
41
|
+
md: "markdown",
|
|
42
|
+
mdx: "markdown",
|
|
43
|
+
bash: "console",
|
|
44
|
+
sh: "console",
|
|
45
|
+
shell: "console",
|
|
46
|
+
zsh: "console",
|
|
47
|
+
python: "python",
|
|
48
|
+
py: "python",
|
|
49
|
+
rust: "rust",
|
|
50
|
+
go: "go",
|
|
51
|
+
java: "java",
|
|
52
|
+
c: "c",
|
|
53
|
+
cpp: "cpp",
|
|
54
|
+
"c++": "cpp",
|
|
55
|
+
swift: "swift",
|
|
56
|
+
kotlin: "kotlin",
|
|
57
|
+
kt: "kotlin",
|
|
58
|
+
yaml: "yaml",
|
|
59
|
+
yml: "yaml",
|
|
60
|
+
sql: "database",
|
|
61
|
+
xml: "xml",
|
|
62
|
+
vue: "vue",
|
|
63
|
+
svelte: "svelte",
|
|
64
|
+
php: "php",
|
|
65
|
+
rb: "ruby",
|
|
66
|
+
lua: "lua",
|
|
67
|
+
zig: "zig",
|
|
68
|
+
toml: "toml",
|
|
69
|
+
graphql: "graphql",
|
|
70
|
+
gql: "graphql",
|
|
71
|
+
dockerfile: "docker"
|
|
72
|
+
};
|
|
73
|
+
function getLanguageIconSvg(lang2) {
|
|
74
|
+
const iconName = LANG_TO_ICON[lang2] ?? "code";
|
|
75
|
+
return getMaterialIconSvg(iconName);
|
|
76
|
+
}
|
|
77
|
+
function hasLanguageIcon(lang2) {
|
|
78
|
+
return getLanguageIconSvg(lang2) !== null;
|
|
79
|
+
}
|
|
80
|
+
const LanguageIcon = ({
|
|
81
|
+
language,
|
|
82
|
+
size = 14,
|
|
83
|
+
className = `${langIcon} ${semanticClassNames.langIcon}`
|
|
84
|
+
}) => {
|
|
85
|
+
const html = useMemo(() => getLanguageIconSvg(language), [language]);
|
|
86
|
+
if (!html) {
|
|
87
|
+
return /* @__PURE__ */ jsx(
|
|
88
|
+
"span",
|
|
89
|
+
{
|
|
90
|
+
className,
|
|
91
|
+
style: {
|
|
92
|
+
width: size,
|
|
93
|
+
height: size,
|
|
94
|
+
display: "inline-flex",
|
|
95
|
+
alignItems: "center",
|
|
96
|
+
justifyContent: "center",
|
|
97
|
+
opacity: 0.6,
|
|
98
|
+
fontSize: size * 0.6
|
|
99
|
+
},
|
|
100
|
+
children: "•"
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return /* @__PURE__ */ jsx(
|
|
105
|
+
"span",
|
|
106
|
+
{
|
|
107
|
+
className,
|
|
108
|
+
style: { width: size, height: size },
|
|
109
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
export {
|
|
114
|
+
LanguageIcon as L,
|
|
115
|
+
copyButton as a,
|
|
116
|
+
bodyBackground as b,
|
|
117
|
+
card as c,
|
|
118
|
+
expandButton as d,
|
|
119
|
+
expandWrap as e,
|
|
120
|
+
scroll as f,
|
|
121
|
+
scrollCollapsed as g,
|
|
122
|
+
hasLanguageIcon as h,
|
|
123
|
+
lined as i,
|
|
124
|
+
linedWithNumbers as j,
|
|
125
|
+
body as k,
|
|
126
|
+
lang as l,
|
|
127
|
+
bodyReadonly as m,
|
|
128
|
+
getMaterialIconSvg as n,
|
|
129
|
+
LANG_TO_ICON as o,
|
|
130
|
+
semanticClassNames as s
|
|
131
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.
|
|
1
|
+
._1pn9r4q0 {
|
|
2
2
|
--rr-code-accent: #737373;
|
|
3
3
|
position: relative;
|
|
4
4
|
margin: 1.5rem 0;
|
|
@@ -6,16 +6,27 @@
|
|
|
6
6
|
overflow: hidden;
|
|
7
7
|
font-size: 14px;
|
|
8
8
|
}
|
|
9
|
-
.
|
|
9
|
+
._1pn9r4q1 {
|
|
10
10
|
position: absolute;
|
|
11
11
|
bottom: 0.75rem;
|
|
12
12
|
right: 0.75rem;
|
|
13
13
|
z-index: 2;
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: 0.375rem;
|
|
14
17
|
font-size: 0.875rem;
|
|
15
18
|
opacity: 0.6;
|
|
16
19
|
pointer-events: none;
|
|
17
20
|
}
|
|
18
|
-
.
|
|
21
|
+
._1pn9r4q2 {
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
}
|
|
25
|
+
._1pn9r4q2 svg {
|
|
26
|
+
width: 100%;
|
|
27
|
+
height: 100%;
|
|
28
|
+
}
|
|
29
|
+
._1pn9r4q3 {
|
|
19
30
|
appearance: none;
|
|
20
31
|
position: absolute;
|
|
21
32
|
right: 0.5rem;
|
|
@@ -34,36 +45,36 @@
|
|
|
34
45
|
transition: opacity 0.2s ease;
|
|
35
46
|
backdrop-filter: blur(8px);
|
|
36
47
|
}
|
|
37
|
-
.
|
|
48
|
+
._1pn9r4q0:hover ._1pn9r4q3 {
|
|
38
49
|
opacity: 1;
|
|
39
50
|
}
|
|
40
|
-
.
|
|
51
|
+
._1pn9r4q4 {
|
|
41
52
|
position: relative;
|
|
42
53
|
background: color-mix(in srgb, var(--rr-code-accent) 5%, transparent);
|
|
43
54
|
padding: 1rem 0;
|
|
44
55
|
}
|
|
45
|
-
.
|
|
56
|
+
._1pn9r4q5 {
|
|
46
57
|
position: relative;
|
|
47
58
|
width: 100%;
|
|
48
59
|
overflow: auto;
|
|
49
60
|
}
|
|
50
|
-
.
|
|
61
|
+
._1pn9r4q6 {
|
|
51
62
|
max-height: 50vh;
|
|
52
63
|
overflow: hidden;
|
|
53
64
|
}
|
|
54
|
-
.
|
|
65
|
+
._1pn9r4q7 {
|
|
55
66
|
position: relative;
|
|
56
67
|
overflow: auto;
|
|
57
68
|
background-color: transparent !important;
|
|
58
69
|
}
|
|
59
|
-
.
|
|
70
|
+
._1pn9r4q7 > .shikicode.output {
|
|
60
71
|
position: static !important;
|
|
61
72
|
inset: auto !important;
|
|
62
73
|
}
|
|
63
|
-
.
|
|
74
|
+
._1pn9r4q8 > textarea.shikicode {
|
|
64
75
|
display: none;
|
|
65
76
|
}
|
|
66
|
-
.
|
|
77
|
+
._1pn9r4q9 {
|
|
67
78
|
position: absolute;
|
|
68
79
|
bottom: 0;
|
|
69
80
|
left: 0;
|
|
@@ -74,7 +85,7 @@
|
|
|
74
85
|
background: linear-gradient(to bottom, transparent 0%, var(--bg, var(--rc-bg-secondary)) 80%);
|
|
75
86
|
pointer-events: none;
|
|
76
87
|
}
|
|
77
|
-
.
|
|
88
|
+
._1pn9r4qa {
|
|
78
89
|
appearance: none;
|
|
79
90
|
border: none;
|
|
80
91
|
background: none;
|
|
@@ -87,46 +98,47 @@
|
|
|
87
98
|
opacity: 0.7;
|
|
88
99
|
pointer-events: auto;
|
|
89
100
|
}
|
|
90
|
-
.
|
|
101
|
+
._1pn9r4qa:hover {
|
|
91
102
|
opacity: 1;
|
|
92
103
|
}
|
|
93
|
-
.
|
|
104
|
+
._1pn9r4q0 pre {
|
|
94
105
|
margin: 0 !important;
|
|
95
106
|
padding: 0 !important;
|
|
96
107
|
border-radius: 0;
|
|
97
108
|
font-size: min(1em, 16px);
|
|
98
109
|
}
|
|
99
|
-
.
|
|
110
|
+
._1pn9r4q0 pre code {
|
|
100
111
|
display: flex;
|
|
101
112
|
flex-direction: column;
|
|
102
113
|
}
|
|
103
|
-
.
|
|
114
|
+
._1pn9r4q0 .shiki, ._1pn9r4q0 code, ._1pn9r4q0 pre {
|
|
104
115
|
background: transparent !important;
|
|
105
116
|
}
|
|
106
|
-
.
|
|
117
|
+
._1pn9r4q0 .shikicode.output .line::before {
|
|
107
118
|
background-color: transparent !important;
|
|
119
|
+
color: color-mix(in srgb, var(--rc-text-secondary) 40%, transparent) !important;
|
|
108
120
|
}
|
|
109
|
-
.
|
|
121
|
+
._1pn9r4q0 .line {
|
|
110
122
|
display: block;
|
|
111
123
|
padding: 0 1.25rem;
|
|
112
124
|
}
|
|
113
|
-
.
|
|
125
|
+
._1pn9r4q0 .shikicode.input.line-numbers {
|
|
114
126
|
padding-left: calc(5em + 1.25rem);
|
|
115
127
|
}
|
|
116
|
-
.
|
|
128
|
+
._1pn9r4q0 .shikicode.input:not(.line-numbers) {
|
|
117
129
|
padding-left: 1.25rem;
|
|
118
130
|
}
|
|
119
|
-
.
|
|
131
|
+
._1pn9r4q0 .line > span:last-child {
|
|
120
132
|
margin-right: 1.25rem;
|
|
121
133
|
}
|
|
122
|
-
.
|
|
134
|
+
._1pn9r4q0 .line::after {
|
|
123
135
|
content: ' ';
|
|
124
136
|
}
|
|
125
|
-
.
|
|
137
|
+
._1pn9r4q0 .highlighted, ._1pn9r4q0 .diff {
|
|
126
138
|
position: relative;
|
|
127
139
|
overflow-wrap: break-word;
|
|
128
140
|
}
|
|
129
|
-
.
|
|
141
|
+
._1pn9r4q0 .highlighted::before, ._1pn9r4q0 .diff::before {
|
|
130
142
|
content: '';
|
|
131
143
|
position: absolute;
|
|
132
144
|
left: 0;
|
|
@@ -134,43 +146,43 @@
|
|
|
134
146
|
height: 100%;
|
|
135
147
|
width: 2px;
|
|
136
148
|
}
|
|
137
|
-
.
|
|
149
|
+
._1pn9r4q0 .highlighted {
|
|
138
150
|
background: color-mix(in srgb, var(--rr-code-accent) 20%, transparent);
|
|
139
151
|
}
|
|
140
|
-
.
|
|
152
|
+
._1pn9r4q0 .highlighted::before {
|
|
141
153
|
background: var(--rr-code-accent);
|
|
142
154
|
}
|
|
143
|
-
.
|
|
155
|
+
._1pn9r4q0 .diff.add {
|
|
144
156
|
background: rgba(34, 197, 94, 0.15);
|
|
145
157
|
}
|
|
146
|
-
.
|
|
158
|
+
._1pn9r4q0 .diff.add::before {
|
|
147
159
|
background: #22c55e;
|
|
148
160
|
}
|
|
149
|
-
.
|
|
161
|
+
._1pn9r4q0 .diff.add::after {
|
|
150
162
|
content: ' +';
|
|
151
163
|
position: absolute;
|
|
152
164
|
left: 0;
|
|
153
165
|
color: #22c55e;
|
|
154
166
|
}
|
|
155
|
-
.
|
|
167
|
+
._1pn9r4q0 .diff.remove {
|
|
156
168
|
background: rgba(239, 68, 68, 0.15);
|
|
157
169
|
}
|
|
158
|
-
.
|
|
170
|
+
._1pn9r4q0 .diff.remove::before {
|
|
159
171
|
background: #ef4444;
|
|
160
172
|
}
|
|
161
|
-
.
|
|
173
|
+
._1pn9r4q0 .diff.remove::after {
|
|
162
174
|
content: ' -';
|
|
163
175
|
position: absolute;
|
|
164
176
|
left: 0;
|
|
165
177
|
color: #ef4444;
|
|
166
178
|
}
|
|
167
|
-
.
|
|
179
|
+
._1pn9r4qb {
|
|
168
180
|
counter-reset: shiki-line 0;
|
|
169
181
|
}
|
|
170
|
-
.
|
|
182
|
+
._1pn9r4qb .line {
|
|
171
183
|
counter-increment: shiki-line 1;
|
|
172
184
|
}
|
|
173
|
-
.
|
|
185
|
+
._1pn9r4qb .line::before {
|
|
174
186
|
content: counter(shiki-line);
|
|
175
187
|
color: transparent;
|
|
176
188
|
text-align: right;
|
|
@@ -180,19 +192,57 @@
|
|
|
180
192
|
position: sticky;
|
|
181
193
|
left: 0;
|
|
182
194
|
}
|
|
183
|
-
.
|
|
195
|
+
._1pn9r4qc .line::before {
|
|
184
196
|
color: inherit;
|
|
185
197
|
opacity: 0.4;
|
|
186
198
|
width: 5em;
|
|
187
199
|
padding-right: 2em;
|
|
188
200
|
}
|
|
189
|
-
.
|
|
201
|
+
._1pn9r4q5 pre::-webkit-scrollbar-track {
|
|
190
202
|
margin-left: 1rem;
|
|
191
203
|
margin-right: var(--sr-margin, 0);
|
|
192
204
|
}
|
|
193
|
-
.
|
|
205
|
+
._1pn9r4q5 pre::-webkit-scrollbar {
|
|
194
206
|
background-color: transparent !important;
|
|
195
207
|
}
|
|
208
|
+
._1pn9r4qd {
|
|
209
|
+
font-family: var(--rc-font-mono);
|
|
210
|
+
font-size: var(--rc-font-size-small);
|
|
211
|
+
background-color: var(--rc-code-bg);
|
|
212
|
+
border-radius: var(--rc-radius-md);
|
|
213
|
+
overflow: hidden;
|
|
214
|
+
margin: var(--rc-space-md) 0;
|
|
215
|
+
border: 1px solid var(--rc-border);
|
|
216
|
+
}
|
|
217
|
+
._1pn9r4qe {
|
|
218
|
+
display: flex;
|
|
219
|
+
align-items: center;
|
|
220
|
+
justify-content: space-between;
|
|
221
|
+
padding: var(--rc-space-sm) var(--rc-space-md);
|
|
222
|
+
border-bottom: 1px solid var(--rc-border);
|
|
223
|
+
font-size: var(--rc-font-size-small);
|
|
224
|
+
color: var(--rc-text-secondary);
|
|
225
|
+
user-select: none;
|
|
226
|
+
}
|
|
227
|
+
._1pn9r4qf {
|
|
228
|
+
font-family: var(--rc-font-mono);
|
|
229
|
+
font-size: 0.85em;
|
|
230
|
+
text-transform: uppercase;
|
|
231
|
+
letter-spacing: 0.05em;
|
|
232
|
+
}
|
|
233
|
+
._1pn9r4qg {
|
|
234
|
+
appearance: none;
|
|
235
|
+
border: none;
|
|
236
|
+
background: none;
|
|
237
|
+
color: var(--rc-text-secondary);
|
|
238
|
+
cursor: pointer;
|
|
239
|
+
padding: var(--rc-space-xs) var(--rc-space-sm);
|
|
240
|
+
border-radius: var(--rc-radius-sm);
|
|
241
|
+
font-family: var(--rc-font-family);
|
|
242
|
+
font-size: var(--rc-font-size-small);
|
|
243
|
+
line-height: 1;
|
|
244
|
+
transition: color 0.15s ease, background-color 0.15s ease;
|
|
245
|
+
}
|
|
196
246
|
.rich-code-block {
|
|
197
247
|
font-family: var(--rc-font-mono);
|
|
198
248
|
font-size: var(--rc-font-size-small);
|
|
@@ -260,7 +310,7 @@
|
|
|
260
310
|
width: 2.5em;
|
|
261
311
|
margin-right: var(--rc-space-md);
|
|
262
312
|
text-align: right;
|
|
263
|
-
color: color-mix(in srgb, var(--rc-text-secondary) 40%, transparent);
|
|
313
|
+
color: color-mix(in srgb, var(--rc-text-secondary) 40%, transparent) !important;
|
|
264
314
|
opacity: 0.4;
|
|
265
315
|
user-select: none;
|
|
266
316
|
font-size: var(--rc-font-size-small);
|
package/dist/shiki.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
let highlighterPromise = null;
|
|
2
|
+
function getHighlighter() {
|
|
3
|
+
if (!highlighterPromise) {
|
|
4
|
+
highlighterPromise = import("shiki/bundle/web").then(
|
|
5
|
+
(mod) => mod.createHighlighter({
|
|
6
|
+
langs: [],
|
|
7
|
+
themes: ["github-light", "github-dark"]
|
|
8
|
+
})
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
return highlighterPromise;
|
|
12
|
+
}
|
|
13
|
+
async function getHighlighterWithLang(language) {
|
|
14
|
+
const highlighter = await getHighlighter();
|
|
15
|
+
if (language && language !== "text" && language !== "plaintext") {
|
|
16
|
+
const loaded = highlighter.getLoadedLanguages();
|
|
17
|
+
if (!loaded.includes(language)) {
|
|
18
|
+
try {
|
|
19
|
+
await highlighter.loadLanguage(language);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return highlighter;
|
|
25
|
+
}
|
|
26
|
+
const SHIKI_THEMES = {
|
|
27
|
+
light: "github-light",
|
|
28
|
+
dark: "github-dark"
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
SHIKI_THEMES,
|
|
32
|
+
getHighlighterWithLang
|
|
33
|
+
};
|
package/dist/styles.css.d.ts
CHANGED
|
@@ -1,2 +1,40 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export declare const semanticClassNames: {
|
|
2
|
+
readonly card: "rr-code-card";
|
|
3
|
+
readonly lang: "rr-code-lang";
|
|
4
|
+
readonly langIcon: "rr-code-lang-icon";
|
|
5
|
+
readonly copyButton: "rr-code-copy";
|
|
6
|
+
readonly bodyBackground: "rr-code-bg";
|
|
7
|
+
readonly scroll: "rr-code-scroll";
|
|
8
|
+
readonly scrollCollapsed: "rr-code-scroll-collapsed";
|
|
9
|
+
readonly body: "rr-code-body";
|
|
10
|
+
readonly bodyReadonly: "rr-code-readonly";
|
|
11
|
+
readonly expandWrap: "rr-code-expand-wrap";
|
|
12
|
+
readonly expandButton: "rr-code-expand";
|
|
13
|
+
readonly lined: "rr-code-lined";
|
|
14
|
+
readonly linedWithNumbers: "rr-code-lined-ln";
|
|
15
|
+
};
|
|
16
|
+
export declare const card: string;
|
|
17
|
+
export declare const lang: string;
|
|
18
|
+
export declare const langIcon: string;
|
|
19
|
+
export declare const copyButton: string;
|
|
20
|
+
export declare const bodyBackground: string;
|
|
21
|
+
export declare const scroll: string;
|
|
22
|
+
export declare const scrollCollapsed: string;
|
|
23
|
+
export declare const body: string;
|
|
24
|
+
export declare const bodyReadonly: string;
|
|
25
|
+
export declare const expandWrap: string;
|
|
26
|
+
export declare const expandButton: string;
|
|
27
|
+
export declare const lined: string;
|
|
28
|
+
export declare const linedWithNumbers: string;
|
|
29
|
+
export declare const contentSemanticClassNames: {
|
|
30
|
+
readonly root: "rich-code-block";
|
|
31
|
+
readonly header: "rich-code-block-header";
|
|
32
|
+
readonly lang: "rich-code-block-lang";
|
|
33
|
+
readonly copyButton: "rich-code-block-copy";
|
|
34
|
+
readonly numbered: "rich-code-block-numbered";
|
|
35
|
+
};
|
|
36
|
+
export declare const contentRoot: string;
|
|
37
|
+
export declare const contentHeader: string;
|
|
38
|
+
export declare const contentLang: string;
|
|
39
|
+
export declare const contentCopyButton: string;
|
|
2
40
|
//# sourceMappingURL=styles.css.d.ts.map
|
package/dist/styles.css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;CAcrB,CAAA;AAGV,eAAO,MAAM,IAAI,QAOf,CAAA;AAGF,eAAO,MAAM,IAAI,QAWf,CAAA;AAEF,eAAO,MAAM,QAAQ,QAGnB,CAAA;AAQF,eAAO,MAAM,UAAU,QAuBrB,CAAA;AAGF,eAAO,MAAM,cAAc,QAIzB,CAAA;AAGF,eAAO,MAAM,MAAM,QAIjB,CAAA;AAEF,eAAO,MAAM,eAAe,QAG1B,CAAA;AAGF,eAAO,MAAM,IAAI,QAIf,CAAA;AAEF,eAAO,MAAM,YAAY,QAAY,CAAA;AAYrC,eAAO,MAAM,UAAU,QAUrB,CAAA;AAEF,eAAO,MAAM,YAAY,QAiBvB,CAAA;AA8FF,eAAO,MAAM,KAAK,QAEhB,CAAA;AAiBF,eAAO,MAAM,gBAAgB,QAAY,CAAA;AAmBzC,eAAO,MAAM,yBAAyB;;;;;;CAM5B,CAAA;AAiFV,eAAO,MAAM,WAAW,QAA2B,CAAA;AACnD,eAAO,MAAM,aAAa,QAA6B,CAAA;AACvD,eAAO,MAAM,WAAW,QAA2B,CAAA;AACnD,eAAO,MAAM,iBAAiB,QAAiC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-renderer-codeblock",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Code block renderer with Shiki syntax highlighting",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,18 +17,24 @@
|
|
|
17
17
|
"import": "./dist/constants.mjs",
|
|
18
18
|
"types": "./dist/constants.d.ts"
|
|
19
19
|
},
|
|
20
|
-
"./style.css": "./dist/rich-renderer-codeblock.css"
|
|
20
|
+
"./style.css": "./dist/rich-renderer-codeblock.css",
|
|
21
|
+
"./icons": {
|
|
22
|
+
"import": "./dist/icons.mjs",
|
|
23
|
+
"types": "./dist/icons.d.ts"
|
|
24
|
+
}
|
|
21
25
|
},
|
|
22
26
|
"main": "./dist/index.mjs",
|
|
23
27
|
"files": [
|
|
24
28
|
"dist"
|
|
25
29
|
],
|
|
26
30
|
"dependencies": {
|
|
31
|
+
"@iconify-json/material-icon-theme": "^1.2.22",
|
|
32
|
+
"@iconify/utils": "^2.3.0",
|
|
27
33
|
"lucide-react": "^0.574.0",
|
|
28
34
|
"shiki": "^3.21.0",
|
|
29
35
|
"shikicode": "*",
|
|
30
|
-
"@haklex/rich-
|
|
31
|
-
"@haklex/rich-
|
|
36
|
+
"@haklex/rich-editor": "0.0.5",
|
|
37
|
+
"@haklex/rich-style-token": "0.0.5"
|
|
32
38
|
},
|
|
33
39
|
"devDependencies": {
|
|
34
40
|
"@types/react": "^19.0.0",
|