@haklex/rich-renderer-codeblock 0.0.65 → 0.0.66
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 +42 -25
- package/dist/CodeBlockCard.d.ts +2 -2
- package/dist/CodeBlockCard.d.ts.map +1 -1
- package/dist/CodeBlockEditRenderer.d.ts +1 -1
- package/dist/CodeBlockEditRenderer.d.ts.map +1 -1
- package/dist/{CodeBlockRenderer-DoVYgPoV.js → CodeBlockRenderer-DSXP75Xm.js} +31 -66
- package/dist/CodeBlockRenderer.d.ts +1 -1
- package/dist/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/LanguageCombobox.d.ts +1 -1
- package/dist/LanguageCombobox.d.ts.map +1 -1
- package/dist/icons/file.d.ts +2 -2
- package/dist/icons/file.d.ts.map +1 -1
- package/dist/icons/language.d.ts.map +1 -1
- package/dist/icons.mjs +5 -10
- package/dist/index.mjs +18 -37
- package/dist/{language-CWZoNKWO.js → language-UrxzhGSS.js} +63 -63
- package/dist/static.mjs +1 -1
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -1,48 +1,65 @@
|
|
|
1
1
|
# @haklex/rich-renderer-codeblock
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Code block renderer with Shiki syntax highlighting for static display and CodeMirror for interactive editing.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @haklex/rich-renderer-codeblock
|
|
8
|
+
pnpm add @haklex/rich-renderer-codeblock
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Peer Dependencies
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
## 功能
|
|
19
|
-
|
|
20
|
-
- Shiki 语法高亮
|
|
21
|
-
- 自动检测语言
|
|
22
|
-
- 行号显示
|
|
23
|
-
- 复制按钮
|
|
24
|
-
- 自动适配深浅主题
|
|
13
|
+
| Package | Version |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `react` | `>=19` |
|
|
16
|
+
| `react-dom` | `>=19` |
|
|
25
17
|
|
|
26
|
-
##
|
|
18
|
+
## Usage
|
|
27
19
|
|
|
28
20
|
```tsx
|
|
29
|
-
import { CodeBlockRenderer } from '@haklex/rich-renderer-codeblock'
|
|
30
|
-
import type { RendererConfig } from '@haklex/rich-editor'
|
|
21
|
+
import { CodeBlockRenderer } from '@haklex/rich-renderer-codeblock/static'
|
|
31
22
|
|
|
32
|
-
|
|
23
|
+
// Register in a static RendererConfig
|
|
24
|
+
const rendererConfig = {
|
|
25
|
+
// ...other renderers
|
|
33
26
|
CodeBlock: CodeBlockRenderer,
|
|
34
27
|
}
|
|
35
28
|
```
|
|
36
29
|
|
|
37
|
-
|
|
30
|
+
For edit mode:
|
|
38
31
|
|
|
39
|
-
```
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
```tsx
|
|
33
|
+
import { CodeBlockEditRenderer } from '@haklex/rich-renderer-codeblock'
|
|
34
|
+
|
|
35
|
+
const editRendererConfig = {
|
|
36
|
+
// ...other renderers
|
|
37
|
+
CodeBlock: CodeBlockEditRenderer,
|
|
43
38
|
}
|
|
44
39
|
```
|
|
45
40
|
|
|
41
|
+
## Exports
|
|
42
|
+
|
|
43
|
+
### Components
|
|
44
|
+
|
|
45
|
+
- `CodeBlockRenderer` — Static (read-only) renderer with Shiki syntax highlighting
|
|
46
|
+
- `CodeBlockEditRenderer` — Edit (interactive) renderer with CodeMirror editor
|
|
47
|
+
|
|
48
|
+
### Sub-path Exports
|
|
49
|
+
|
|
50
|
+
| Path | Description |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `@haklex/rich-renderer-codeblock` | Full exports (edit + static) |
|
|
53
|
+
| `@haklex/rich-renderer-codeblock/static` | Static-only renderer |
|
|
54
|
+
| `@haklex/rich-renderer-codeblock/shiki` | Shiki highlighting utilities |
|
|
55
|
+
| `@haklex/rich-renderer-codeblock/constants` | Language and theme constants |
|
|
56
|
+
| `@haklex/rich-renderer-codeblock/icons` | Language icons |
|
|
57
|
+
| `@haklex/rich-renderer-codeblock/style.css` | Stylesheet |
|
|
58
|
+
|
|
59
|
+
## Part of Haklex
|
|
60
|
+
|
|
61
|
+
This package is part of the [Haklex](../../README.md) rich editor ecosystem.
|
|
62
|
+
|
|
46
63
|
## License
|
|
47
64
|
|
|
48
65
|
MIT
|
package/dist/CodeBlockCard.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
interface CodeBlockCardProps {
|
|
3
|
+
children: ReactNode;
|
|
3
4
|
code: string;
|
|
4
|
-
language: string;
|
|
5
5
|
collapsible?: boolean;
|
|
6
6
|
langSlot?: ReactNode;
|
|
7
|
-
|
|
7
|
+
language: string;
|
|
8
8
|
}
|
|
9
9
|
export declare function CodeBlockCard({ code, language, collapsible, langSlot, children, }: CodeBlockCardProps): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockCard.d.ts","sourceRoot":"","sources":["../src/CodeBlockCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"CodeBlockCard.d.ts","sourceRoot":"","sources":["../src/CodeBlockCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAWtD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,QAAQ,EACR,WAAkB,EAClB,QAAQ,EACR,QAAQ,GACT,EAAE,kBAAkB,2CAgGpB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeBlockRendererProps } from '@haklex/rich-editor';
|
|
1
|
+
import { CodeBlockRendererProps } from '@haklex/rich-editor/renderers';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
export declare const CodeBlockEditRenderer: ComponentType<CodeBlockRendererProps>;
|
|
4
4
|
//# sourceMappingURL=CodeBlockEditRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockEditRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockEditRenderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CodeBlockEditRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockEditRenderer.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAc3C,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,sBAAsB,CA+PvE,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { Check, Copy, ChevronDown } from "lucide-react";
|
|
|
4
4
|
import { normalizeLanguage, getLanguageDisplayName, languageToColorMap } from "./constants.mjs";
|
|
5
5
|
import "@iconify/utils";
|
|
6
6
|
import "@iconify-json/material-icon-theme";
|
|
7
|
-
import { i as card, s as semanticClassNames, l as lang, h as hasLanguageIcon, a as LanguageIcon, j as copyButton, k as bodyBackground, m as expandWrap, n as expandButton, o as scroll, p as scrollCollapsed, c as lined, d as linedWithNumbers } from "./language-
|
|
7
|
+
import { i as card, s as semanticClassNames, l as lang, h as hasLanguageIcon, a as LanguageIcon, j as copyButton, k as bodyBackground, m as expandWrap, n as expandButton, o as scroll, p as scrollCollapsed, c as lined, d as linedWithNumbers } from "./language-UrxzhGSS.js";
|
|
8
8
|
import { getHighlighterWithLang, SHIKI_DUAL_THEMES } from "./shiki.mjs";
|
|
9
9
|
const CopyIcon = /* @__PURE__ */ jsx(Copy, { size: 16 });
|
|
10
10
|
const CheckIcon = /* @__PURE__ */ jsx(Check, { size: 16 });
|
|
@@ -49,70 +49,41 @@ function CodeBlockCard({
|
|
|
49
49
|
}, [code]);
|
|
50
50
|
const languageLabel = getLanguageDisplayName(normalizedLanguage);
|
|
51
51
|
const accent = languageToColorMap[normalizedLanguage] || "#737373";
|
|
52
|
-
const cardStyle = useMemo(
|
|
53
|
-
() => ({ "--rr-code-accent": accent }),
|
|
54
|
-
[accent]
|
|
55
|
-
);
|
|
52
|
+
const cardStyle = useMemo(() => ({ "--rr-code-accent": accent }), [accent]);
|
|
56
53
|
const scrollClassName = [
|
|
57
54
|
scroll,
|
|
58
55
|
semanticClassNames.scroll,
|
|
59
56
|
collapsible && isCollapsed && isOverflow && scrollCollapsed,
|
|
60
57
|
collapsible && isCollapsed && isOverflow && semanticClassNames.scrollCollapsed
|
|
61
58
|
].filter(Boolean).join(" ");
|
|
62
|
-
return /* @__PURE__ */ jsxs(
|
|
63
|
-
"div",
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
children: [
|
|
91
|
-
/* @__PURE__ */ jsx("div", { ref: scrollRef, className: scrollClassName, children }),
|
|
92
|
-
collapsible && isOverflow && isCollapsed && /* @__PURE__ */ jsx(
|
|
93
|
-
"div",
|
|
94
|
-
{
|
|
95
|
-
className: `${expandWrap} ${semanticClassNames.expandWrap}`,
|
|
96
|
-
children: /* @__PURE__ */ jsxs(
|
|
97
|
-
"button",
|
|
98
|
-
{
|
|
99
|
-
type: "button",
|
|
100
|
-
className: `${expandButton} ${semanticClassNames.expandButton}`,
|
|
101
|
-
onClick: () => setIsCollapsed(false),
|
|
102
|
-
children: [
|
|
103
|
-
ExpandIcon,
|
|
104
|
-
/* @__PURE__ */ jsx("span", { children: "展开" })
|
|
105
|
-
]
|
|
106
|
-
}
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
)
|
|
110
|
-
]
|
|
111
|
-
}
|
|
112
|
-
)
|
|
113
|
-
]
|
|
114
|
-
}
|
|
115
|
-
);
|
|
59
|
+
return /* @__PURE__ */ jsxs("div", { className: `${card} ${semanticClassNames.card}`, style: cardStyle, children: [
|
|
60
|
+
langSlot ?? (normalizedLanguage !== "text" && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: `${lang} ${semanticClassNames.lang}`, children: hasLanguageIcon(normalizedLanguage) ? /* @__PURE__ */ jsx(LanguageIcon, { language: normalizedLanguage, size: 14 }) : /* @__PURE__ */ jsx("span", { children: languageLabel }) })),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"button",
|
|
63
|
+
{
|
|
64
|
+
"aria-label": copied ? "Copied" : "Copy code",
|
|
65
|
+
className: `${copyButton} ${semanticClassNames.copyButton}`,
|
|
66
|
+
type: "button",
|
|
67
|
+
onClick: handleCopy,
|
|
68
|
+
children: copied ? CheckIcon : CopyIcon
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: `${bodyBackground} ${semanticClassNames.bodyBackground}`, children: [
|
|
72
|
+
/* @__PURE__ */ jsx("div", { className: scrollClassName, ref: scrollRef, children }),
|
|
73
|
+
collapsible && isOverflow && isCollapsed && /* @__PURE__ */ jsx("div", { className: `${expandWrap} ${semanticClassNames.expandWrap}`, children: /* @__PURE__ */ jsxs(
|
|
74
|
+
"button",
|
|
75
|
+
{
|
|
76
|
+
className: `${expandButton} ${semanticClassNames.expandButton}`,
|
|
77
|
+
type: "button",
|
|
78
|
+
onClick: () => setIsCollapsed(false),
|
|
79
|
+
children: [
|
|
80
|
+
ExpandIcon,
|
|
81
|
+
/* @__PURE__ */ jsx("span", { children: "展开" })
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
) })
|
|
85
|
+
] })
|
|
86
|
+
] });
|
|
116
87
|
}
|
|
117
88
|
const CodeBlockRenderer = ({
|
|
118
89
|
code,
|
|
@@ -146,13 +117,7 @@ const CodeBlockRenderer = ({
|
|
|
146
117
|
showLineNumbers && linedWithNumbers,
|
|
147
118
|
showLineNumbers && semanticClassNames.linedWithNumbers
|
|
148
119
|
].filter(Boolean).join(" ");
|
|
149
|
-
return /* @__PURE__ */ jsx(CodeBlockCard, { code, language, children: html ? /* @__PURE__ */ jsx(
|
|
150
|
-
"div",
|
|
151
|
-
{
|
|
152
|
-
className: linedClassName,
|
|
153
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
154
|
-
}
|
|
155
|
-
) : /* @__PURE__ */ jsx("pre", { className: linedClassName, children: /* @__PURE__ */ jsx("code", { children: fallbackLines.map((line, i) => /* @__PURE__ */ jsx("span", { className: "line", children: line }, i)) }) }) });
|
|
120
|
+
return /* @__PURE__ */ jsx(CodeBlockCard, { code, language, children: html ? /* @__PURE__ */ jsx("div", { className: linedClassName, dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsx("pre", { className: linedClassName, children: /* @__PURE__ */ jsx("code", { children: fallbackLines.map((line, i) => /* @__PURE__ */ jsx("span", { className: "line", children: line }, i)) }) }) });
|
|
156
121
|
};
|
|
157
122
|
export {
|
|
158
123
|
CodeBlockRenderer as C,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeBlockRendererProps } from '@haklex/rich-editor';
|
|
1
|
+
import { CodeBlockRendererProps } from '@haklex/rich-editor/renderers';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
export declare const CodeBlockRenderer: ComponentType<CodeBlockRendererProps>;
|
|
4
4
|
export default CodeBlockRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"CodeBlockRenderer.d.ts","sourceRoot":"","sources":["../src/CodeBlockRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAQ3C,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,sBAAsB,CA2DnE,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -2,6 +2,6 @@ interface LanguageComboboxProps {
|
|
|
2
2
|
language: string;
|
|
3
3
|
onLanguageChange?: (language: string) => void;
|
|
4
4
|
}
|
|
5
|
-
export declare function LanguageCombobox({ language, onLanguageChange
|
|
5
|
+
export declare function LanguageCombobox({ language, onLanguageChange }: LanguageComboboxProps): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export {};
|
|
7
7
|
//# sourceMappingURL=LanguageCombobox.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageCombobox.d.ts","sourceRoot":"","sources":["../src/LanguageCombobox.tsx"],"names":[],"mappings":"AAoBA,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"LanguageCombobox.d.ts","sourceRoot":"","sources":["../src/LanguageCombobox.tsx"],"names":[],"mappings":"AAoBA,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,qBAAqB,2CAkDrF"}
|
package/dist/icons/file.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { FC, ReactNode } from 'react';
|
|
|
2
2
|
/** Maps file extension to material-icon-theme icon name. */
|
|
3
3
|
export declare const EXT_TO_ICON: Record<string, string>;
|
|
4
4
|
export interface FileIconProps {
|
|
5
|
-
filename: string;
|
|
6
|
-
size?: number;
|
|
7
5
|
/** Optional class for the wrapper (e.g. consumer styles). */
|
|
8
6
|
className?: string;
|
|
9
7
|
/** Fallback when no icon is found. Default "F". */
|
|
10
8
|
fallback?: ReactNode;
|
|
9
|
+
filename: string;
|
|
10
|
+
size?: number;
|
|
11
11
|
}
|
|
12
12
|
export declare const FileIcon: FC<FileIconProps>;
|
|
13
13
|
//# sourceMappingURL=file.d.ts.map
|
package/dist/icons/file.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,CAAC;AAK3C,4DAA4D;AAC5D,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkD9C,CAAC;AAQF,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CA4BtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/icons/language.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/icons/language.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,iEAAiE;AACjE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAoE/C,CAAC;AAOF,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAiCA,CAAC"}
|
package/dist/icons.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
-
import { g as getMaterialIconSvg } from "./language-
|
|
4
|
-
import { L, a, h } from "./language-
|
|
3
|
+
import { g as getMaterialIconSvg } from "./language-UrxzhGSS.js";
|
|
4
|
+
import { L, a, h } from "./language-UrxzhGSS.js";
|
|
5
5
|
const EXT_TO_ICON = {
|
|
6
6
|
ts: "typescript",
|
|
7
7
|
tsx: "react-ts",
|
|
@@ -59,12 +59,7 @@ function getFileIconSvg(filename) {
|
|
|
59
59
|
const iconName = EXT_TO_ICON[ext] ?? "file";
|
|
60
60
|
return getMaterialIconSvg(iconName);
|
|
61
61
|
}
|
|
62
|
-
const FileIcon = ({
|
|
63
|
-
filename,
|
|
64
|
-
size = 16,
|
|
65
|
-
className,
|
|
66
|
-
fallback = "F"
|
|
67
|
-
}) => {
|
|
62
|
+
const FileIcon = ({ filename, size = 16, className, fallback = "F" }) => {
|
|
68
63
|
const html = useMemo(() => getFileIconSvg(filename), [filename]);
|
|
69
64
|
const wrapperStyle = {
|
|
70
65
|
width: size,
|
|
@@ -82,8 +77,8 @@ const FileIcon = ({
|
|
|
82
77
|
"span",
|
|
83
78
|
{
|
|
84
79
|
className,
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
dangerouslySetInnerHTML: { __html: html },
|
|
81
|
+
style: { width: size, height: size }
|
|
87
82
|
}
|
|
88
83
|
);
|
|
89
84
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -5,22 +5,19 @@ import { EditorView, keymap, lineNumbers } from "@codemirror/view";
|
|
|
5
5
|
import { isOnFirstLine, isOnLastLine, getThemeExtensions, loadLanguageExtension } from "@haklex/cm-editor";
|
|
6
6
|
import { useVariant, useColorScheme } from "@haklex/rich-editor";
|
|
7
7
|
import { useCallback, useMemo, useState, useRef, useEffect } from "react";
|
|
8
|
-
import { a as CodeBlockCard } from "./CodeBlockRenderer-
|
|
9
|
-
import { C } from "./CodeBlockRenderer-
|
|
8
|
+
import { a as CodeBlockCard } from "./CodeBlockRenderer-DSXP75Xm.js";
|
|
9
|
+
import { C } from "./CodeBlockRenderer-DSXP75Xm.js";
|
|
10
10
|
import { normalizeLanguage } from "./constants.mjs";
|
|
11
11
|
import { Combobox, ComboboxInput, ComboboxContent, ComboboxEmpty, ComboboxList, ComboboxItem } from "@haklex/rich-editor-ui";
|
|
12
12
|
import { bundledLanguagesInfo } from "shiki/bundle/web";
|
|
13
13
|
import "@iconify/utils";
|
|
14
14
|
import "@iconify-json/material-icon-theme";
|
|
15
|
-
import { l as lang, s as semanticClassNames, h as hasLanguageIcon, a as LanguageIcon, b as langInput, c as lined, d as linedWithNumbers, e as body, f as bodyReadonly } from "./language-
|
|
15
|
+
import { l as lang, s as semanticClassNames, h as hasLanguageIcon, a as LanguageIcon, b as langInput, c as lined, d as linedWithNumbers, e as body, f as bodyReadonly } from "./language-UrxzhGSS.js";
|
|
16
16
|
const languageItems = bundledLanguagesInfo.map((info) => ({
|
|
17
17
|
id: info.id,
|
|
18
18
|
name: info.name
|
|
19
19
|
}));
|
|
20
|
-
function LanguageCombobox({
|
|
21
|
-
language,
|
|
22
|
-
onLanguageChange
|
|
23
|
-
}) {
|
|
20
|
+
function LanguageCombobox({ language, onLanguageChange }) {
|
|
24
21
|
const normalizedLanguage = normalizeLanguage(language);
|
|
25
22
|
const handleValueChange = useCallback(
|
|
26
23
|
(value) => {
|
|
@@ -39,11 +36,11 @@ function LanguageCombobox({
|
|
|
39
36
|
/* @__PURE__ */ jsxs(
|
|
40
37
|
Combobox,
|
|
41
38
|
{
|
|
42
|
-
value: selectedValue,
|
|
43
|
-
onValueChange: handleValueChange,
|
|
44
|
-
itemToStringValue: (item) => item.id,
|
|
45
39
|
itemToStringLabel: (item) => item.id,
|
|
40
|
+
itemToStringValue: (item) => item.id,
|
|
46
41
|
items: languageItems,
|
|
42
|
+
value: selectedValue,
|
|
43
|
+
onValueChange: handleValueChange,
|
|
47
44
|
children: [
|
|
48
45
|
/* @__PURE__ */ jsx(
|
|
49
46
|
ComboboxInput,
|
|
@@ -55,7 +52,7 @@ function LanguageCombobox({
|
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
),
|
|
58
|
-
/* @__PURE__ */ jsxs(ComboboxContent, { side: "top", sideOffset: 8,
|
|
55
|
+
/* @__PURE__ */ jsxs(ComboboxContent, { align: "end", side: "top", sideOffset: 8, children: [
|
|
59
56
|
/* @__PURE__ */ jsx(ComboboxEmpty, { children: "No languages found." }),
|
|
60
57
|
/* @__PURE__ */ jsx(ComboboxList, { children: (item) => /* @__PURE__ */ jsxs(ComboboxItem, { value: item, children: [
|
|
61
58
|
/* @__PURE__ */ jsx(LanguageIcon, { language: item.id, size: 16 }),
|
|
@@ -104,14 +101,10 @@ const CodeBlockEditRenderer = ({
|
|
|
104
101
|
const editableCompartmentRef = useRef(null);
|
|
105
102
|
const lineNumbersCompartmentRef = useRef(null);
|
|
106
103
|
const themeCompartmentRef = useRef(null);
|
|
107
|
-
if (!languageCompartmentRef.current)
|
|
108
|
-
|
|
109
|
-
if (!
|
|
110
|
-
|
|
111
|
-
if (!lineNumbersCompartmentRef.current)
|
|
112
|
-
lineNumbersCompartmentRef.current = new Compartment();
|
|
113
|
-
if (!themeCompartmentRef.current)
|
|
114
|
-
themeCompartmentRef.current = new Compartment();
|
|
104
|
+
if (!languageCompartmentRef.current) languageCompartmentRef.current = new Compartment();
|
|
105
|
+
if (!editableCompartmentRef.current) editableCompartmentRef.current = new Compartment();
|
|
106
|
+
if (!lineNumbersCompartmentRef.current) lineNumbersCompartmentRef.current = new Compartment();
|
|
107
|
+
if (!themeCompartmentRef.current) themeCompartmentRef.current = new Compartment();
|
|
115
108
|
const keyboardBoundaryHandler = useMemo(
|
|
116
109
|
() => Prec.high(
|
|
117
110
|
EditorView.domEventHandlers({
|
|
@@ -163,9 +156,7 @@ const CodeBlockEditRenderer = ({
|
|
|
163
156
|
EditorView.editable.of(editable),
|
|
164
157
|
EditorState.readOnly.of(!editable)
|
|
165
158
|
]),
|
|
166
|
-
lineNumbersCompartmentRef.current.of(
|
|
167
|
-
showLineNumbers ? lineNumbers() : []
|
|
168
|
-
),
|
|
159
|
+
lineNumbersCompartmentRef.current.of(showLineNumbers ? lineNumbers() : []),
|
|
169
160
|
themeCompartmentRef.current.of(getThemeExtensions(colorScheme)),
|
|
170
161
|
languageCompartmentRef.current.of([])
|
|
171
162
|
]
|
|
@@ -193,18 +184,14 @@ const CodeBlockEditRenderer = ({
|
|
|
193
184
|
const editor = editorRef.current;
|
|
194
185
|
if (!editor) return;
|
|
195
186
|
editor.dispatch({
|
|
196
|
-
effects: lineNumbersCompartmentRef.current.reconfigure(
|
|
197
|
-
showLineNumbers ? lineNumbers() : []
|
|
198
|
-
)
|
|
187
|
+
effects: lineNumbersCompartmentRef.current.reconfigure(showLineNumbers ? lineNumbers() : [])
|
|
199
188
|
});
|
|
200
189
|
}, [showLineNumbers]);
|
|
201
190
|
useEffect(() => {
|
|
202
191
|
const editor = editorRef.current;
|
|
203
192
|
if (!editor) return;
|
|
204
193
|
editor.dispatch({
|
|
205
|
-
effects: themeCompartmentRef.current.reconfigure(
|
|
206
|
-
getThemeExtensions(colorScheme)
|
|
207
|
-
)
|
|
194
|
+
effects: themeCompartmentRef.current.reconfigure(getThemeExtensions(colorScheme))
|
|
208
195
|
});
|
|
209
196
|
}, [colorScheme]);
|
|
210
197
|
useEffect(() => {
|
|
@@ -268,22 +255,16 @@ const CodeBlockEditRenderer = ({
|
|
|
268
255
|
CodeBlockCard,
|
|
269
256
|
{
|
|
270
257
|
code,
|
|
271
|
-
language,
|
|
272
258
|
collapsible: !editable,
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
{
|
|
276
|
-
language,
|
|
277
|
-
onLanguageChange
|
|
278
|
-
}
|
|
279
|
-
) : void 0,
|
|
259
|
+
language,
|
|
260
|
+
langSlot: editable ? /* @__PURE__ */ jsx(LanguageCombobox, { language, onLanguageChange }) : void 0,
|
|
280
261
|
children: [
|
|
281
262
|
!mounted && /* @__PURE__ */ jsx("pre", { className: fallbackClassName, children: /* @__PURE__ */ jsx("code", { children: fallbackLines.map((line, i) => /* @__PURE__ */ jsx("span", { className: "line", children: line }, `${line}-${i}`)) }) }),
|
|
282
263
|
/* @__PURE__ */ jsx(
|
|
283
264
|
"div",
|
|
284
265
|
{
|
|
285
|
-
ref: containerRef,
|
|
286
266
|
className: bodyClassName,
|
|
267
|
+
ref: containerRef,
|
|
287
268
|
style: !mounted ? { height: 0, overflow: "hidden", visibility: "hidden" } : void 0
|
|
288
269
|
}
|
|
289
270
|
)
|
|
@@ -24,73 +24,73 @@ var expandButton = "_1pn9r4qb";
|
|
|
24
24
|
var lined = "_1pn9r4qc";
|
|
25
25
|
var linedWithNumbers = "_1pn9r4qd";
|
|
26
26
|
const LANG_TO_ICON = {
|
|
27
|
-
javascript: "javascript",
|
|
28
|
-
js: "javascript",
|
|
29
|
-
typescript: "typescript",
|
|
30
|
-
ts: "typescript",
|
|
27
|
+
"javascript": "javascript",
|
|
28
|
+
"js": "javascript",
|
|
29
|
+
"typescript": "typescript",
|
|
30
|
+
"ts": "typescript",
|
|
31
31
|
"angular-ts": "angular",
|
|
32
32
|
"angular-html": "angular",
|
|
33
|
-
jsx: "react",
|
|
34
|
-
tsx: "react",
|
|
35
|
-
html: "html",
|
|
33
|
+
"jsx": "react",
|
|
34
|
+
"tsx": "react",
|
|
35
|
+
"html": "html",
|
|
36
36
|
"html-derivative": "html",
|
|
37
|
-
css: "css",
|
|
38
|
-
scss: "sass",
|
|
39
|
-
sass: "sass",
|
|
40
|
-
less: "sass",
|
|
41
|
-
postcss: "postcss",
|
|
42
|
-
stylus: "stylus",
|
|
43
|
-
json: "json",
|
|
44
|
-
json5: "json",
|
|
45
|
-
jsonc: "json",
|
|
46
|
-
jsonl: "json",
|
|
47
|
-
markdown: "markdown",
|
|
48
|
-
md: "markdown",
|
|
49
|
-
mdx: "markdown",
|
|
50
|
-
mdc: "markdown",
|
|
51
|
-
bash: "console",
|
|
52
|
-
sh: "console",
|
|
53
|
-
shell: "console",
|
|
54
|
-
shellscript: "console",
|
|
55
|
-
zsh: "console",
|
|
56
|
-
python: "python",
|
|
57
|
-
py: "python",
|
|
58
|
-
rust: "rust",
|
|
59
|
-
go: "go",
|
|
60
|
-
java: "java",
|
|
61
|
-
c: "c",
|
|
62
|
-
cpp: "cpp",
|
|
37
|
+
"css": "css",
|
|
38
|
+
"scss": "sass",
|
|
39
|
+
"sass": "sass",
|
|
40
|
+
"less": "sass",
|
|
41
|
+
"postcss": "postcss",
|
|
42
|
+
"stylus": "stylus",
|
|
43
|
+
"json": "json",
|
|
44
|
+
"json5": "json",
|
|
45
|
+
"jsonc": "json",
|
|
46
|
+
"jsonl": "json",
|
|
47
|
+
"markdown": "markdown",
|
|
48
|
+
"md": "markdown",
|
|
49
|
+
"mdx": "markdown",
|
|
50
|
+
"mdc": "markdown",
|
|
51
|
+
"bash": "console",
|
|
52
|
+
"sh": "console",
|
|
53
|
+
"shell": "console",
|
|
54
|
+
"shellscript": "console",
|
|
55
|
+
"zsh": "console",
|
|
56
|
+
"python": "python",
|
|
57
|
+
"py": "python",
|
|
58
|
+
"rust": "rust",
|
|
59
|
+
"go": "go",
|
|
60
|
+
"java": "java",
|
|
61
|
+
"c": "c",
|
|
62
|
+
"cpp": "cpp",
|
|
63
63
|
"c++": "cpp",
|
|
64
|
-
swift: "swift",
|
|
65
|
-
kotlin: "kotlin",
|
|
66
|
-
kt: "kotlin",
|
|
67
|
-
yaml: "yaml",
|
|
68
|
-
yml: "yaml",
|
|
69
|
-
sql: "database",
|
|
70
|
-
xml: "xml",
|
|
71
|
-
vue: "vue",
|
|
64
|
+
"swift": "swift",
|
|
65
|
+
"kotlin": "kotlin",
|
|
66
|
+
"kt": "kotlin",
|
|
67
|
+
"yaml": "yaml",
|
|
68
|
+
"yml": "yaml",
|
|
69
|
+
"sql": "database",
|
|
70
|
+
"xml": "xml",
|
|
71
|
+
"vue": "vue",
|
|
72
72
|
"vue-html": "vue",
|
|
73
73
|
"vue-vine": "vue",
|
|
74
|
-
svelte: "svelte",
|
|
75
|
-
astro: "astro",
|
|
76
|
-
php: "php",
|
|
77
|
-
rb: "ruby",
|
|
78
|
-
r: "r",
|
|
79
|
-
julia: "julia",
|
|
80
|
-
lua: "lua",
|
|
81
|
-
zig: "zig",
|
|
82
|
-
toml: "toml",
|
|
83
|
-
graphql: "graphql",
|
|
84
|
-
gql: "graphql",
|
|
85
|
-
dockerfile: "docker",
|
|
86
|
-
coffee: "coffee",
|
|
87
|
-
pug: "pug",
|
|
88
|
-
haml: "haml",
|
|
89
|
-
handlebars: "handlebars",
|
|
90
|
-
marko: "markojs",
|
|
91
|
-
imba: "imba",
|
|
92
|
-
hurl: "hurl",
|
|
93
|
-
http: "http"
|
|
74
|
+
"svelte": "svelte",
|
|
75
|
+
"astro": "astro",
|
|
76
|
+
"php": "php",
|
|
77
|
+
"rb": "ruby",
|
|
78
|
+
"r": "r",
|
|
79
|
+
"julia": "julia",
|
|
80
|
+
"lua": "lua",
|
|
81
|
+
"zig": "zig",
|
|
82
|
+
"toml": "toml",
|
|
83
|
+
"graphql": "graphql",
|
|
84
|
+
"gql": "graphql",
|
|
85
|
+
"dockerfile": "docker",
|
|
86
|
+
"coffee": "coffee",
|
|
87
|
+
"pug": "pug",
|
|
88
|
+
"haml": "haml",
|
|
89
|
+
"handlebars": "handlebars",
|
|
90
|
+
"marko": "markojs",
|
|
91
|
+
"imba": "imba",
|
|
92
|
+
"hurl": "hurl",
|
|
93
|
+
"http": "http"
|
|
94
94
|
};
|
|
95
95
|
function getLanguageIconSvg(lang2) {
|
|
96
96
|
const iconName = LANG_TO_ICON[lang2] ?? "code";
|
|
@@ -127,8 +127,8 @@ const LanguageIcon = ({
|
|
|
127
127
|
"span",
|
|
128
128
|
{
|
|
129
129
|
className,
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
dangerouslySetInnerHTML: { __html: html },
|
|
131
|
+
style: { width: size, height: size }
|
|
132
132
|
}
|
|
133
133
|
);
|
|
134
134
|
};
|
package/dist/static.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-renderer-codeblock",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.66",
|
|
5
5
|
"description": "Code block renderer with Shiki syntax highlighting",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"exports": {
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"@iconify/utils": "^3.1.0",
|
|
44
44
|
"lucide-react": "^0.577.0",
|
|
45
45
|
"shiki": "^4.0.1",
|
|
46
|
-
"@haklex/
|
|
47
|
-
"@haklex/
|
|
48
|
-
"@haklex/rich-editor": "0.0.
|
|
49
|
-
"@haklex/rich-style-token": "0.0.
|
|
46
|
+
"@haklex/cm-editor": "0.0.66",
|
|
47
|
+
"@haklex/rich-editor-ui": "0.0.66",
|
|
48
|
+
"@haklex/rich-editor": "0.0.66",
|
|
49
|
+
"@haklex/rich-style-token": "0.0.66"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/react": "^19.2.14",
|
|
@@ -62,6 +62,11 @@
|
|
|
62
62
|
"publishConfig": {
|
|
63
63
|
"access": "public"
|
|
64
64
|
},
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "https://github.com/Innei/haklex.git",
|
|
68
|
+
"directory": "packages/rich-renderer-codeblock"
|
|
69
|
+
},
|
|
65
70
|
"scripts": {
|
|
66
71
|
"build": "vite build",
|
|
67
72
|
"dev:build": "vite build --watch"
|