c063 1.3.2 → 1.4.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/dist/components/CodeBlock.d.ts +1 -1
- package/dist/components/CodeLine.d.ts +1 -1
- package/dist/components/CodeToken.d.ts +1 -1
- package/dist/components/CodeToken.js +12 -3
- package/dist/libs/index.d.ts +2 -18
- package/dist/libs/index.js +15 -30
- package/dist/libs/themes/default-dark-modern.d.ts +2 -0
- package/dist/libs/themes/default-dark-modern.js +16 -0
- package/dist/libs/themes/default-dark-plus.d.ts +2 -0
- package/dist/libs/themes/default-dark-plus.js +16 -0
- package/dist/libs/themes/default-dark.d.ts +2 -0
- package/dist/libs/themes/default-dark.js +16 -0
- package/dist/libs/themes/default-light-modern.d.ts +2 -0
- package/dist/libs/themes/default-light-modern.js +16 -0
- package/dist/libs/themes/default-light-plus.d.ts +2 -0
- package/dist/libs/themes/default-light-plus.js +16 -0
- package/dist/libs/themes/github-dark-colorblind.d.ts +2 -0
- package/dist/libs/themes/github-dark-colorblind.js +16 -0
- package/dist/libs/themes/github-dark-default.d.ts +2 -0
- package/dist/libs/themes/github-dark-default.js +16 -0
- package/dist/libs/themes/github-dark.d.ts +2 -0
- package/dist/libs/themes/github-dark.js +16 -0
- package/dist/libs/themes/github-light-colorblind.d.ts +2 -0
- package/dist/libs/themes/github-light-colorblind.js +16 -0
- package/dist/libs/themes/github-light-default.d.ts +2 -0
- package/dist/libs/themes/github-light-default.js +16 -0
- package/dist/libs/themes/github-light.d.ts +2 -0
- package/dist/libs/themes/github-light.js +16 -0
- package/dist/libs/themes/visual-studio-light.d.ts +2 -0
- package/dist/libs/themes/visual-studio-light.js +16 -0
- package/dist/types/index.d.ts +117 -2
- package/dist/types/index.js +1 -2
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/parser.d.ts +1 -0
- package/dist/utils/parser.js +26 -0
- package/dist/utils/theme.d.ts +2 -0
- package/dist/utils/theme.js +4 -0
- package/package.json +1 -1
- package/src/components/CodeBlock.tsx +1 -1
- package/src/components/CodeLine.tsx +1 -1
- package/src/components/CodeToken.tsx +16 -3
- package/src/libs/index.tsx +15 -38
- package/src/libs/{default-dark-modern.tsx → themes/default-dark-modern.tsx} +1 -1
- package/src/libs/{default-dark-plus.tsx → themes/default-dark-plus.tsx} +1 -1
- package/src/libs/{default-dark.tsx → themes/default-dark.tsx} +1 -1
- package/src/libs/{default-light-modern.tsx → themes/default-light-modern.tsx} +1 -1
- package/src/libs/{default-light-plus.tsx → themes/default-light-plus.tsx} +1 -1
- package/src/libs/{github-dark-colorblind.tsx → themes/github-dark-colorblind.tsx} +1 -1
- package/src/libs/{github-dark-default.tsx → themes/github-dark-default.tsx} +2 -3
- package/src/libs/{github-dark.tsx → themes/github-dark.tsx} +1 -1
- package/src/libs/{github-light-colorblind.tsx → themes/github-light-colorblind.tsx} +1 -1
- package/src/libs/{github-light-default.tsx → themes/github-light-default.tsx} +1 -1
- package/src/libs/{github-light.tsx → themes/github-light.tsx} +1 -1
- package/src/libs/{visual-studio-light.tsx → themes/visual-studio-light.tsx} +1 -2
- package/src/types/index.ts +147 -2
- package/src/utils/{index.ts → index.tsx} +3 -1
- package/src/utils/parser.tsx +38 -0
- package/src/utils/theme.tsx +8 -0
- package/eslint.config.js +0 -13
- package/src/types/props.tsx +0 -145
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useLayoutEffect, useState } from "react";
|
|
3
|
+
import { loadTheme } from "../utils/theme";
|
|
3
4
|
/**
|
|
4
5
|
* 渲染單一語法 token(例如關鍵字、字串、註解等),可指定標籤與樣式。
|
|
5
6
|
*
|
|
@@ -13,8 +14,16 @@ import { themeMap } from "../libs";
|
|
|
13
14
|
*/
|
|
14
15
|
export const CodeToken = ({ as, style, children, type, theme, ...rest }) => {
|
|
15
16
|
const Tag = as || "span";
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const [currTheme, setCurrTheme] = useState(null);
|
|
18
|
+
useLayoutEffect(() => {
|
|
19
|
+
if (theme) {
|
|
20
|
+
loadTheme(theme).then((res) => setCurrTheme(res));
|
|
21
|
+
}
|
|
22
|
+
}, [theme]);
|
|
23
|
+
return (
|
|
24
|
+
// eslint-disable-next-line react/react-in-jsx-scope
|
|
25
|
+
_jsx(Tag, { ...rest, style: {
|
|
26
|
+
color: (currTheme === null || currTheme === void 0 ? void 0 : currTheme[type || "default"]) || undefined,
|
|
18
27
|
...style,
|
|
19
28
|
}, children: children }));
|
|
20
29
|
};
|
package/dist/libs/index.d.ts
CHANGED
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
declare const
|
|
3
|
-
readonly "default-dark-modern": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
4
|
-
readonly "default-dark": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
5
|
-
readonly "default-dark-plus": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
6
|
-
readonly "visual-studio-light": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
7
|
-
readonly "default-light-plus": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
8
|
-
readonly "default-light-modern": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
9
|
-
readonly "github-light": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
10
|
-
readonly "github-light-default": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
11
|
-
readonly "github-light-colorblind": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
12
|
-
readonly "github-dark": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
13
|
-
readonly "github-dark-default": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
14
|
-
readonly "github-dark-colorblind": Record<CodeTokenType, import("csstype").Property.Color | undefined>;
|
|
15
|
-
};
|
|
16
|
-
export declare const themes: (keyof typeof _themeRegistry)[];
|
|
17
|
-
export declare const themeMap: Record<CodeTheme, Record<CodeTokenType, React.CSSProperties["color"]>>;
|
|
18
|
-
export {};
|
|
1
|
+
export declare const themes: readonly ["default-dark-modern", "default-dark", "default-dark-plus", "visual-studio-light", "default-light-plus", "default-light-modern", "github-light", "github-light-default", "github-light-colorblind", "github-dark", "github-dark-default", "github-dark-colorblind"];
|
|
2
|
+
export declare const parsableLanguages: readonly ["javascript"];
|
package/dist/libs/index.js
CHANGED
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"default-dark-plus": darkPlus,
|
|
17
|
-
"visual-studio-light": vsLight,
|
|
18
|
-
"default-light-plus": lightPlus,
|
|
19
|
-
"default-light-modern": lightModern,
|
|
20
|
-
"github-light": ghLight,
|
|
21
|
-
"github-light-default": ghLightDefault,
|
|
22
|
-
"github-light-colorblind": ghLightBilnd,
|
|
23
|
-
"github-dark": ghDark,
|
|
24
|
-
"github-dark-default": ghDarkDefault,
|
|
25
|
-
"github-dark-colorblind": ghDarkBilnd,
|
|
26
|
-
};
|
|
27
|
-
// 自動推導主題名稱
|
|
28
|
-
export const themes = Object.keys(_themeRegistry);
|
|
29
|
-
// themeMap 保留給外部使用
|
|
30
|
-
export const themeMap = _themeRegistry;
|
|
1
|
+
export const themes = [
|
|
2
|
+
"default-dark-modern",
|
|
3
|
+
"default-dark",
|
|
4
|
+
"default-dark-plus",
|
|
5
|
+
"visual-studio-light",
|
|
6
|
+
"default-light-plus",
|
|
7
|
+
"default-light-modern",
|
|
8
|
+
"github-light",
|
|
9
|
+
"github-light-default",
|
|
10
|
+
"github-light-colorblind",
|
|
11
|
+
"github-dark",
|
|
12
|
+
"github-dark-default",
|
|
13
|
+
"github-dark-colorblind",
|
|
14
|
+
];
|
|
15
|
+
export const parsableLanguages = ["javascript"];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#dcdcaa",
|
|
3
|
+
keyword1: "#569cd6",
|
|
4
|
+
keyword2: "#c586c0",
|
|
5
|
+
string: "#ce9178",
|
|
6
|
+
number: "#b5cea8",
|
|
7
|
+
comment: "#6a9955",
|
|
8
|
+
variable: "#9cdcfe",
|
|
9
|
+
constant: "#4fc1ff",
|
|
10
|
+
type: "#4ec9b0",
|
|
11
|
+
brackets1: "#ffd700",
|
|
12
|
+
brackets2: "#da70d6",
|
|
13
|
+
brackets3: "#179fff",
|
|
14
|
+
operator: "#d4d4d4",
|
|
15
|
+
default: "#d4d4d4",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#dcdcaa",
|
|
3
|
+
keyword1: "#569cd6",
|
|
4
|
+
keyword2: "#c586c0",
|
|
5
|
+
string: "#ce9178",
|
|
6
|
+
number: "#b5cea8",
|
|
7
|
+
comment: "#6a9955",
|
|
8
|
+
variable: "#9cdcfe",
|
|
9
|
+
constant: "#4fc1ff",
|
|
10
|
+
type: "#4ec9b0",
|
|
11
|
+
brackets1: "#ffd700",
|
|
12
|
+
brackets2: "#da70d6",
|
|
13
|
+
brackets3: "#179fff",
|
|
14
|
+
operator: "#d4d4d4",
|
|
15
|
+
default: "#d4d4d4",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#d4d4d4",
|
|
3
|
+
keyword1: "#569cd6",
|
|
4
|
+
keyword2: "#569cd6",
|
|
5
|
+
string: "#ce9178",
|
|
6
|
+
number: "#b5cea8",
|
|
7
|
+
comment: "#6a9955",
|
|
8
|
+
variable: "#d4d4d4",
|
|
9
|
+
constant: "#d4d4d4",
|
|
10
|
+
type: "#d4d4d4",
|
|
11
|
+
brackets1: "#ffd700",
|
|
12
|
+
brackets2: "#da70d6",
|
|
13
|
+
brackets3: "#179fff",
|
|
14
|
+
operator: "#d4d4d4",
|
|
15
|
+
default: "#d4d4d4",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "rgb(121, 94, 38)",
|
|
3
|
+
keyword1: "rgb(0, 0, 255)",
|
|
4
|
+
keyword2: "rgb(175, 0, 219)",
|
|
5
|
+
string: "rgb(163, 21, 21)",
|
|
6
|
+
number: "rgb(9, 134, 88)",
|
|
7
|
+
comment: "rgb(0, 128, 0)",
|
|
8
|
+
variable: "rgb(0, 16, 128)",
|
|
9
|
+
constant: "rgb(0, 112, 193)",
|
|
10
|
+
type: "rgb(0, 0, 255)",
|
|
11
|
+
brackets1: "rgb(4, 49, 250)",
|
|
12
|
+
brackets2: "rgb(49, 147, 49)",
|
|
13
|
+
brackets3: "rgb(123, 56, 20)",
|
|
14
|
+
operator: "rgb(0, 0, 0)",
|
|
15
|
+
default: "rgb(0, 0, 0)",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#795e26",
|
|
3
|
+
keyword1: "#0000ff",
|
|
4
|
+
keyword2: "#af00db",
|
|
5
|
+
string: "#a31515",
|
|
6
|
+
number: "#098658",
|
|
7
|
+
comment: "#008000",
|
|
8
|
+
variable: "#001080",
|
|
9
|
+
constant: "#0070c1",
|
|
10
|
+
type: "#267f99",
|
|
11
|
+
brackets1: "#0431fa",
|
|
12
|
+
brackets2: "#319331",
|
|
13
|
+
brackets3: "#7b3814",
|
|
14
|
+
operator: "#000000",
|
|
15
|
+
default: "#000000",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "rgb(210, 168, 255)",
|
|
3
|
+
keyword1: "rgb(236, 142, 44)",
|
|
4
|
+
keyword2: "rgb(236, 142, 44)",
|
|
5
|
+
string: "rgb(165, 214, 255)",
|
|
6
|
+
number: "rgb(121, 192, 255)",
|
|
7
|
+
comment: "#rgb(139, 148, 158)",
|
|
8
|
+
variable: "rgb(201, 209, 217)",
|
|
9
|
+
constant: "rgb(121, 192, 255)",
|
|
10
|
+
type: "rgb(236, 142, 44)",
|
|
11
|
+
brackets1: "rgb(121, 192, 255)",
|
|
12
|
+
brackets2: "rgb(121, 192, 255)",
|
|
13
|
+
brackets3: "rgb(227, 179, 65)",
|
|
14
|
+
operator: "rgb(236, 142, 44)",
|
|
15
|
+
default: "rgb(201, 209, 217)",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#d2a8ff",
|
|
3
|
+
keyword1: "#ff7b72",
|
|
4
|
+
keyword2: "#ff7b72",
|
|
5
|
+
string: "#a5d6ff",
|
|
6
|
+
number: "#79c0ff",
|
|
7
|
+
comment: "#6a737d",
|
|
8
|
+
variable: "#e6edf3",
|
|
9
|
+
constant: "#79c0ff",
|
|
10
|
+
type: "#ff7b72",
|
|
11
|
+
brackets1: "#79c0ff",
|
|
12
|
+
brackets2: "#56d364",
|
|
13
|
+
brackets3: "#e3b341",
|
|
14
|
+
operator: "#ff7b72",
|
|
15
|
+
default: "#e6edf3",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#b392f0",
|
|
3
|
+
keyword1: "#f97583",
|
|
4
|
+
keyword2: "#f97583",
|
|
5
|
+
string: "#9ecbff",
|
|
6
|
+
number: "#79b8ff",
|
|
7
|
+
comment: "##6a737d",
|
|
8
|
+
variable: "#e1e4e8",
|
|
9
|
+
constant: "#79b8ff",
|
|
10
|
+
type: "#f97583",
|
|
11
|
+
brackets1: "#79b8ff",
|
|
12
|
+
brackets2: "#ffab70",
|
|
13
|
+
brackets3: "#b392f0",
|
|
14
|
+
operator: "#f97583",
|
|
15
|
+
default: "#e1e4e8",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#8250df",
|
|
3
|
+
keyword1: "#b35900",
|
|
4
|
+
keyword2: "#b35900",
|
|
5
|
+
string: "#0a3069",
|
|
6
|
+
number: "#0550ae",
|
|
7
|
+
comment: "#6e7781",
|
|
8
|
+
variable: "#24292f",
|
|
9
|
+
constant: "#0550ae",
|
|
10
|
+
type: "#b35900",
|
|
11
|
+
brackets1: "#0969da",
|
|
12
|
+
brackets2: "#0969da",
|
|
13
|
+
brackets3: "#9a6700",
|
|
14
|
+
operator: "#b35900",
|
|
15
|
+
default: "#24292f",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#8250df",
|
|
3
|
+
keyword1: "#cf222e",
|
|
4
|
+
keyword2: "#cf222e",
|
|
5
|
+
string: "#0a3069",
|
|
6
|
+
number: "##0550ae",
|
|
7
|
+
comment: "#6e7781",
|
|
8
|
+
variable: "#1f2328",
|
|
9
|
+
constant: "#0550ae",
|
|
10
|
+
type: "#cf222e",
|
|
11
|
+
brackets1: "#0969da",
|
|
12
|
+
brackets2: "#1a7f37",
|
|
13
|
+
brackets3: "#9a6700",
|
|
14
|
+
operator: "#cf222e",
|
|
15
|
+
default: "#24292e",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#6f42c1",
|
|
3
|
+
keyword1: "#d73a49",
|
|
4
|
+
keyword2: "#d73a49",
|
|
5
|
+
string: "#032f62",
|
|
6
|
+
number: "#005cc5",
|
|
7
|
+
comment: "#6a737d",
|
|
8
|
+
variable: "#24292e",
|
|
9
|
+
constant: "#0070c1",
|
|
10
|
+
type: "#6f42c1",
|
|
11
|
+
brackets1: "#005cc5",
|
|
12
|
+
brackets2: "#e36209",
|
|
13
|
+
brackets3: "#5a32a3",
|
|
14
|
+
operator: "#d73a49",
|
|
15
|
+
default: "#24292e",
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const map = {
|
|
2
|
+
function: "#000000",
|
|
3
|
+
keyword1: "#0000ff",
|
|
4
|
+
keyword2: "#0000ff",
|
|
5
|
+
string: "#a31515",
|
|
6
|
+
number: "#098658",
|
|
7
|
+
comment: "#008000",
|
|
8
|
+
variable: "#000000",
|
|
9
|
+
constant: "#000000",
|
|
10
|
+
type: "#000000",
|
|
11
|
+
brackets1: "#0431fa",
|
|
12
|
+
brackets2: "#319331",
|
|
13
|
+
brackets3: "#7b3814",
|
|
14
|
+
operator: "#000000",
|
|
15
|
+
default: "#800000",
|
|
16
|
+
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,117 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { parsableLanguages, themes } from "../libs";
|
|
2
|
+
import { AsComponentProps, OverrideProps } from "./common";
|
|
3
|
+
/**
|
|
4
|
+
* 用於表示語法高亮中每個 token 的語意分類,對應於 `<CodeToken />` 中的 `type`。
|
|
5
|
+
*
|
|
6
|
+
* 每個類型會對應特定的顏色與用途,例如關鍵字、數字、字串、註解等,
|
|
7
|
+
* 可配合 `codeColoreMap` 指定顯示樣式。s
|
|
8
|
+
*
|
|
9
|
+
* 類型分為以下幾大類:
|
|
10
|
+
*
|
|
11
|
+
* - `keyword1` / `keyword2`: 關鍵字,如 `const`、`return`、`import` 等,分顏色類別。
|
|
12
|
+
* - `string`: 字串常值,如 `'text'`、`"value"`。
|
|
13
|
+
* - `number`: 數字常值,如 `123`、`3.14`。
|
|
14
|
+
* - `comment`: 註解內容,如 `//`。
|
|
15
|
+
* - `type`: 類型定義,如 `interface`、`enum`、`type`。
|
|
16
|
+
* - `variable`: 識別符號,如變數名、函式名、類別名。
|
|
17
|
+
* - `constant`: 常數或靜態值,如 `PI`、`MAX_VALUE`。
|
|
18
|
+
* - `brackets1 | brackets2 | brackets3`: 括號配對,區分不同層級的括號。
|
|
19
|
+
* - `operator`: 運算符,如 `=`, `+`, `===`, `<`, `>=`。
|
|
20
|
+
* - `default`: 其他符號,如 `;`, `,`, `.`, `?`, `"`, `'`。
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const token: CodeTokenType = "keyword1";
|
|
24
|
+
* const token2: CodeTokenType = "string";
|
|
25
|
+
*/
|
|
26
|
+
export type CodeTokenType = `keyword${1 | 2}` | "function" | "string" | "number" | "comment" | "type" | "variable" | "constant" | `brackets${1 | 2 | 3}` | "operator" | "default";
|
|
27
|
+
/**
|
|
28
|
+
* 表示可用的語法高亮主題名稱。
|
|
29
|
+
* 對應 `themes` 陣列中定義的名稱,例如 `"vscode-dark"`。
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const theme: CodeTheme = "vscode-dark";
|
|
33
|
+
*/
|
|
34
|
+
export type CodeTheme = (typeof themes)[number];
|
|
35
|
+
/**
|
|
36
|
+
* 單一語法 token 的屬性,用於 <CodeToken /> 元件。
|
|
37
|
+
*
|
|
38
|
+
* @template T HTML 或客製元素,例如 span、a、Link 等
|
|
39
|
+
*/
|
|
40
|
+
export type CodeTokenProps<T extends React.ElementType> = AsComponentProps<T, {
|
|
41
|
+
/**
|
|
42
|
+
* 語法 token 的語意類型,用於指定樣式顏色。
|
|
43
|
+
*/
|
|
44
|
+
type?: CodeTokenType;
|
|
45
|
+
/**
|
|
46
|
+
* 語法主題名稱。
|
|
47
|
+
* @default "vscode-dark"
|
|
48
|
+
*/
|
|
49
|
+
theme?: CodeTheme;
|
|
50
|
+
}>;
|
|
51
|
+
export type CodeTokenBuilder = <T extends React.ElementType>(children: CodeTokenProps<T>["children"], props?: CodeTokenProps<T>) => CodeTokenProps<T>;
|
|
52
|
+
/**
|
|
53
|
+
* 用於單一程式碼行的屬性,用在 <CodeLine /> 或類似元件中。
|
|
54
|
+
*/
|
|
55
|
+
export type CodeLineProps<T extends React.ElementType> = OverrideProps<React.HTMLAttributes<HTMLElement>, {
|
|
56
|
+
/**
|
|
57
|
+
* 該行所包含的語法 token。
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```tsx
|
|
61
|
+
* <CodeLine tokens={[
|
|
62
|
+
* { type: "keyword-blue", children: "const" },
|
|
63
|
+
* { type: "variable", children: "myVar" },
|
|
64
|
+
* { type: "operator", children: "=" },
|
|
65
|
+
* { type: "string", children: "'Hello'" },
|
|
66
|
+
* ]} />
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
tokens: CodeTokenProps<T>[];
|
|
70
|
+
/**
|
|
71
|
+
* 語法主題名稱。
|
|
72
|
+
* @default "vscode-dark"
|
|
73
|
+
*/
|
|
74
|
+
theme?: CodeTheme;
|
|
75
|
+
}>;
|
|
76
|
+
export type CodeBlockProps<T extends React.ElementType> = OverrideProps<React.HTMLAttributes<HTMLPreElement>, {
|
|
77
|
+
/**
|
|
78
|
+
* 所有程式碼行的 token 陣列。
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <CodeBlock tokenLines={[
|
|
83
|
+
* [
|
|
84
|
+
* { type: "keyword-blue", children: "const" },
|
|
85
|
+
* { type: "variable", children: "x" },
|
|
86
|
+
* { type: "operator", children: "=" },
|
|
87
|
+
* { type: "number", children: "42" },
|
|
88
|
+
* ],
|
|
89
|
+
* [
|
|
90
|
+
* { type: "keyword-purple", children: "return" },
|
|
91
|
+
* { type: "variable", children: "x" },
|
|
92
|
+
* ],
|
|
93
|
+
* ]} />
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
tokenLines: CodeTokenProps<T>[][];
|
|
97
|
+
/**
|
|
98
|
+
* 是否顯示行號。
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
showLineNumbers?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* 行號的樣式。
|
|
104
|
+
* @default { color: "#888", fontSize: "0.8em" }
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* <CodeBlock lineNumberStyle={{ color: "#888", fontSize: "0.8em" }} />
|
|
108
|
+
* ```
|
|
109
|
+
* */
|
|
110
|
+
lineNumberStyle?: React.CSSProperties;
|
|
111
|
+
/**
|
|
112
|
+
* 語法主題名稱。
|
|
113
|
+
* @default "vscode-dark"
|
|
114
|
+
*/
|
|
115
|
+
theme?: CodeTheme;
|
|
116
|
+
}>;
|
|
117
|
+
export type ParsableLanguage = (typeof parsableLanguages)[number];
|
package/dist/types/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from "./props";
|
|
1
|
+
export {};
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { CodeTokenBuilder, CodeTokenProps, CodeTokenType } from "../types";
|
|
|
15
15
|
*
|
|
16
16
|
* @returns 一個以 `CodeTokenType` 為 key 的建構器函式集合
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
declare const c063: Record<CodeTokenType, CodeTokenBuilder>;
|
|
19
19
|
/**
|
|
20
20
|
* 產生指定空白數量的 CodeToken,用於程式碼中的縮排或空格。
|
|
21
21
|
*
|
|
@@ -26,3 +26,4 @@ export declare const c063: Record<CodeTokenType, CodeTokenBuilder>;
|
|
|
26
26
|
* tokens.push(whiteSpace(2)); // -> { type: "default", children: " " }
|
|
27
27
|
*/
|
|
28
28
|
export declare const whiteSpace: (count?: number) => CodeTokenProps<"span">;
|
|
29
|
+
export default c063;
|
package/dist/utils/index.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @returns 一個以 `CodeTokenType` 為 key 的建構器函式集合
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
const c063 = new Proxy({}, {
|
|
18
18
|
get: (_, prop) => {
|
|
19
19
|
const builder = (children, props) => {
|
|
20
20
|
return {
|
|
@@ -36,3 +36,4 @@ export const c063 = new Proxy({}, {
|
|
|
36
36
|
* tokens.push(whiteSpace(2)); // -> { type: "default", children: " " }
|
|
37
37
|
*/
|
|
38
38
|
export const whiteSpace = (count = 1) => c063.default(" ".repeat(count));
|
|
39
|
+
export default c063;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { parsableLanguages } from "../libs";
|
|
2
|
+
const isParsableLanguage = (lang) => {
|
|
3
|
+
return parsableLanguages.includes(lang);
|
|
4
|
+
};
|
|
5
|
+
// 解析單行 CodeTokenProps
|
|
6
|
+
const _parseTokenLine = (line, lang) => {
|
|
7
|
+
if (!isParsableLanguage(lang))
|
|
8
|
+
return [];
|
|
9
|
+
const result = [];
|
|
10
|
+
// 這邊放對應語言的解析邏輯或呼叫外部 parser
|
|
11
|
+
// 目前先用預設行全文字 token
|
|
12
|
+
result.push({ type: "default", children: line });
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
const parseTokenLines = new Proxy({}, {
|
|
16
|
+
get: (_, prop) => (content) => content.split("\n").map((line) => _parseTokenLine(line, prop)),
|
|
17
|
+
});
|
|
18
|
+
// parseTokenLines.javascript(
|
|
19
|
+
// `const FanYu = {
|
|
20
|
+
// name: '范余振富',
|
|
21
|
+
// nickname: '飯魚',
|
|
22
|
+
// age: 19, // <-點看看🤫
|
|
23
|
+
// hobbies: ['寫程式', '繪畫'],
|
|
24
|
+
// skills: ['TypeScript', 'React', 'Python'],
|
|
25
|
+
// } as const;`
|
|
26
|
+
// );
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "c063",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"description": "A React component for displaying code snippets with syntax highlighting.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CodeTokenProps } from "../types/
|
|
1
|
+
import { useLayoutEffect, useState } from "react";
|
|
2
|
+
import { CodeTokenProps, CodeTokenType } from "../types/index";
|
|
3
|
+
import { loadTheme } from "../utils/theme";
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* 渲染單一語法 token(例如關鍵字、字串、註解等),可指定標籤與樣式。
|
|
5
7
|
*
|
|
@@ -20,12 +22,23 @@ export const CodeToken = <T extends React.ElementType = "span">({
|
|
|
20
22
|
...rest
|
|
21
23
|
}: CodeTokenProps<T>) => {
|
|
22
24
|
const Tag = as || "span";
|
|
25
|
+
const [currTheme, setCurrTheme] = useState<Record<
|
|
26
|
+
CodeTokenType,
|
|
27
|
+
React.CSSProperties["color"]
|
|
28
|
+
> | null>(null);
|
|
29
|
+
|
|
30
|
+
useLayoutEffect(() => {
|
|
31
|
+
if (theme) {
|
|
32
|
+
loadTheme(theme).then((res) => setCurrTheme(res));
|
|
33
|
+
}
|
|
34
|
+
}, [theme]);
|
|
23
35
|
|
|
24
36
|
return (
|
|
37
|
+
// eslint-disable-next-line react/react-in-jsx-scope
|
|
25
38
|
<Tag
|
|
26
39
|
{...rest}
|
|
27
40
|
style={{
|
|
28
|
-
color:
|
|
41
|
+
color: currTheme?.[type || "default"] || undefined,
|
|
29
42
|
...style,
|
|
30
43
|
}}
|
|
31
44
|
>
|
package/src/libs/index.tsx
CHANGED
|
@@ -1,39 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
export const themes = [
|
|
2
|
+
"default-dark-modern",
|
|
3
|
+
"default-dark",
|
|
4
|
+
"default-dark-plus",
|
|
5
|
+
"visual-studio-light",
|
|
6
|
+
"default-light-plus",
|
|
7
|
+
"default-light-modern",
|
|
8
|
+
"github-light",
|
|
9
|
+
"github-light-default",
|
|
10
|
+
"github-light-colorblind",
|
|
11
|
+
"github-dark",
|
|
12
|
+
"github-dark-default",
|
|
13
|
+
"github-dark-colorblind",
|
|
14
|
+
] as const;
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
-
"default-dark-modern": darkModern,
|
|
17
|
-
"default-dark": dark,
|
|
18
|
-
"default-dark-plus": darkPlus,
|
|
19
|
-
"visual-studio-light": vsLight,
|
|
20
|
-
"default-light-plus": lightPlus,
|
|
21
|
-
"default-light-modern": lightModern,
|
|
22
|
-
"github-light": ghLight,
|
|
23
|
-
"github-light-default": ghLightDefault,
|
|
24
|
-
"github-light-colorblind": ghLightBilnd,
|
|
25
|
-
"github-dark": ghDark,
|
|
26
|
-
"github-dark-default": ghDarkDefault,
|
|
27
|
-
"github-dark-colorblind": ghDarkBilnd,
|
|
28
|
-
} as const;
|
|
29
|
-
|
|
30
|
-
// 自動推導主題名稱
|
|
31
|
-
export const themes = Object.keys(
|
|
32
|
-
_themeRegistry
|
|
33
|
-
) as (keyof typeof _themeRegistry)[];
|
|
34
|
-
|
|
35
|
-
// themeMap 保留給外部使用
|
|
36
|
-
export const themeMap: Record<
|
|
37
|
-
CodeTheme,
|
|
38
|
-
Record<CodeTokenType, React.CSSProperties["color"]>
|
|
39
|
-
> = _themeRegistry;
|
|
16
|
+
export const parsableLanguages = ["javascript"] as const;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeTokenType } from "
|
|
1
|
+
import { CodeTokenType } from "../../types";
|
|
2
2
|
|
|
3
3
|
export const map: Record<CodeTokenType, React.CSSProperties["color"]> = {
|
|
4
4
|
function: "#d2a8ff",
|
|
@@ -6,14 +6,13 @@ export const map: Record<CodeTokenType, React.CSSProperties["color"]> = {
|
|
|
6
6
|
keyword2: "#ff7b72",
|
|
7
7
|
string: "#a5d6ff",
|
|
8
8
|
number: "#79c0ff",
|
|
9
|
-
comment: "
|
|
9
|
+
comment: "#6a737d",
|
|
10
10
|
variable: "#e6edf3",
|
|
11
11
|
constant: "#79c0ff",
|
|
12
12
|
type: "#ff7b72",
|
|
13
13
|
brackets1: "#79c0ff",
|
|
14
14
|
brackets2: "#56d364",
|
|
15
15
|
brackets3: "#e3b341",
|
|
16
|
-
brackets4: "#ffa198",
|
|
17
16
|
operator: "#ff7b72",
|
|
18
17
|
default: "#e6edf3",
|
|
19
18
|
};
|
package/src/types/index.ts
CHANGED
|
@@ -1,2 +1,147 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { parsableLanguages, themes } from "../libs";
|
|
2
|
+
import { AsComponentProps, OverrideProps } from "./common";
|
|
3
|
+
/**
|
|
4
|
+
* 用於表示語法高亮中每個 token 的語意分類,對應於 `<CodeToken />` 中的 `type`。
|
|
5
|
+
*
|
|
6
|
+
* 每個類型會對應特定的顏色與用途,例如關鍵字、數字、字串、註解等,
|
|
7
|
+
* 可配合 `codeColoreMap` 指定顯示樣式。s
|
|
8
|
+
*
|
|
9
|
+
* 類型分為以下幾大類:
|
|
10
|
+
*
|
|
11
|
+
* - `keyword1` / `keyword2`: 關鍵字,如 `const`、`return`、`import` 等,分顏色類別。
|
|
12
|
+
* - `string`: 字串常值,如 `'text'`、`"value"`。
|
|
13
|
+
* - `number`: 數字常值,如 `123`、`3.14`。
|
|
14
|
+
* - `comment`: 註解內容,如 `//`。
|
|
15
|
+
* - `type`: 類型定義,如 `interface`、`enum`、`type`。
|
|
16
|
+
* - `variable`: 識別符號,如變數名、函式名、類別名。
|
|
17
|
+
* - `constant`: 常數或靜態值,如 `PI`、`MAX_VALUE`。
|
|
18
|
+
* - `brackets1 | brackets2 | brackets3`: 括號配對,區分不同層級的括號。
|
|
19
|
+
* - `operator`: 運算符,如 `=`, `+`, `===`, `<`, `>=`。
|
|
20
|
+
* - `default`: 其他符號,如 `;`, `,`, `.`, `?`, `"`, `'`。
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const token: CodeTokenType = "keyword1";
|
|
24
|
+
* const token2: CodeTokenType = "string";
|
|
25
|
+
*/
|
|
26
|
+
export type CodeTokenType =
|
|
27
|
+
| `keyword${1 | 2}` // 關鍵字,分兩種樣式
|
|
28
|
+
| "function" // 函式名
|
|
29
|
+
| "string" // 字串常值:'abc'、"hello"
|
|
30
|
+
| "number" // 數值常量:123、3.14
|
|
31
|
+
| "comment" // 註解內容:// 或 /* */
|
|
32
|
+
| "type" // 類型定義:type、interface、enum
|
|
33
|
+
| "variable" // 變數名、函式名、類別名等識別符號
|
|
34
|
+
| "constant" // 常數值:例如 enum 值、靜態屬性
|
|
35
|
+
| `brackets${1 | 2 | 3}` // 括號配對,多層不同樣式:(), [], {}
|
|
36
|
+
| "operator" // 運算符號:=、+、*、===、<、>= 等
|
|
37
|
+
| "default"; // 其他符號:, ; . ? ! 等
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 表示可用的語法高亮主題名稱。
|
|
41
|
+
* 對應 `themes` 陣列中定義的名稱,例如 `"vscode-dark"`。
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const theme: CodeTheme = "vscode-dark";
|
|
45
|
+
*/
|
|
46
|
+
export type CodeTheme = (typeof themes)[number];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 單一語法 token 的屬性,用於 <CodeToken /> 元件。
|
|
50
|
+
*
|
|
51
|
+
* @template T HTML 或客製元素,例如 span、a、Link 等
|
|
52
|
+
*/
|
|
53
|
+
export type CodeTokenProps<T extends React.ElementType> = AsComponentProps<
|
|
54
|
+
T,
|
|
55
|
+
{
|
|
56
|
+
/**
|
|
57
|
+
* 語法 token 的語意類型,用於指定樣式顏色。
|
|
58
|
+
*/
|
|
59
|
+
type?: CodeTokenType;
|
|
60
|
+
/**
|
|
61
|
+
* 語法主題名稱。
|
|
62
|
+
* @default "vscode-dark"
|
|
63
|
+
*/
|
|
64
|
+
theme?: CodeTheme;
|
|
65
|
+
}
|
|
66
|
+
>;
|
|
67
|
+
|
|
68
|
+
export type CodeTokenBuilder = <T extends React.ElementType>(
|
|
69
|
+
children: CodeTokenProps<T>["children"],
|
|
70
|
+
props?: CodeTokenProps<T>
|
|
71
|
+
) => CodeTokenProps<T>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 用於單一程式碼行的屬性,用在 <CodeLine /> 或類似元件中。
|
|
75
|
+
*/
|
|
76
|
+
export type CodeLineProps<T extends React.ElementType> = OverrideProps<
|
|
77
|
+
React.HTMLAttributes<HTMLElement>,
|
|
78
|
+
{
|
|
79
|
+
/**
|
|
80
|
+
* 該行所包含的語法 token。
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* <CodeLine tokens={[
|
|
85
|
+
* { type: "keyword-blue", children: "const" },
|
|
86
|
+
* { type: "variable", children: "myVar" },
|
|
87
|
+
* { type: "operator", children: "=" },
|
|
88
|
+
* { type: "string", children: "'Hello'" },
|
|
89
|
+
* ]} />
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
tokens: CodeTokenProps<T>[];
|
|
93
|
+
/**
|
|
94
|
+
* 語法主題名稱。
|
|
95
|
+
* @default "vscode-dark"
|
|
96
|
+
*/
|
|
97
|
+
theme?: CodeTheme;
|
|
98
|
+
}
|
|
99
|
+
>;
|
|
100
|
+
|
|
101
|
+
export type CodeBlockProps<T extends React.ElementType> = OverrideProps<
|
|
102
|
+
React.HTMLAttributes<HTMLPreElement>,
|
|
103
|
+
{
|
|
104
|
+
/**
|
|
105
|
+
* 所有程式碼行的 token 陣列。
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```tsx
|
|
109
|
+
* <CodeBlock tokenLines={[
|
|
110
|
+
* [
|
|
111
|
+
* { type: "keyword-blue", children: "const" },
|
|
112
|
+
* { type: "variable", children: "x" },
|
|
113
|
+
* { type: "operator", children: "=" },
|
|
114
|
+
* { type: "number", children: "42" },
|
|
115
|
+
* ],
|
|
116
|
+
* [
|
|
117
|
+
* { type: "keyword-purple", children: "return" },
|
|
118
|
+
* { type: "variable", children: "x" },
|
|
119
|
+
* ],
|
|
120
|
+
* ]} />
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
tokenLines: CodeTokenProps<T>[][];
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 是否顯示行號。
|
|
127
|
+
* @default true
|
|
128
|
+
*/
|
|
129
|
+
showLineNumbers?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* 行號的樣式。
|
|
132
|
+
* @default { color: "#888", fontSize: "0.8em" }
|
|
133
|
+
* @example
|
|
134
|
+
* ```tsx
|
|
135
|
+
* <CodeBlock lineNumberStyle={{ color: "#888", fontSize: "0.8em" }} />
|
|
136
|
+
* ```
|
|
137
|
+
* */
|
|
138
|
+
lineNumberStyle?: React.CSSProperties;
|
|
139
|
+
/**
|
|
140
|
+
* 語法主題名稱。
|
|
141
|
+
* @default "vscode-dark"
|
|
142
|
+
*/
|
|
143
|
+
theme?: CodeTheme;
|
|
144
|
+
}
|
|
145
|
+
>;
|
|
146
|
+
|
|
147
|
+
export type ParsableLanguage = (typeof parsableLanguages)[number];
|
|
@@ -15,7 +15,7 @@ import { CodeTokenBuilder, CodeTokenProps, CodeTokenType } from "../types";
|
|
|
15
15
|
*
|
|
16
16
|
* @returns 一個以 `CodeTokenType` 為 key 的建構器函式集合
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
const c063 = new Proxy(
|
|
19
19
|
{},
|
|
20
20
|
{
|
|
21
21
|
get: (_, prop: CodeTokenType) => {
|
|
@@ -45,3 +45,5 @@ export const c063 = new Proxy(
|
|
|
45
45
|
*/
|
|
46
46
|
export const whiteSpace = (count: number = 1): CodeTokenProps<"span"> =>
|
|
47
47
|
c063.default(" ".repeat(count));
|
|
48
|
+
|
|
49
|
+
export default c063;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { parsableLanguages } from "../libs";
|
|
2
|
+
import { CodeTokenProps, ParsableLanguage } from "../types/index";
|
|
3
|
+
|
|
4
|
+
const isParsableLanguage = (lang: string): lang is ParsableLanguage => {
|
|
5
|
+
return parsableLanguages.includes(lang as ParsableLanguage);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// 解析單行 CodeTokenProps
|
|
9
|
+
const _parseTokenLine = (
|
|
10
|
+
line: string,
|
|
11
|
+
lang: ParsableLanguage
|
|
12
|
+
): CodeTokenProps<"span">[] => {
|
|
13
|
+
if (!isParsableLanguage(lang)) return [];
|
|
14
|
+
const result: CodeTokenProps<"span">[] = [];
|
|
15
|
+
// 這邊放對應語言的解析邏輯或呼叫外部 parser
|
|
16
|
+
// 目前先用預設行全文字 token
|
|
17
|
+
result.push({ type: "default", children: line });
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
const parseTokenLines = new Proxy(
|
|
21
|
+
{},
|
|
22
|
+
{
|
|
23
|
+
get:
|
|
24
|
+
(_, prop: ParsableLanguage) =>
|
|
25
|
+
(content: string): CodeTokenProps<"span">[][] =>
|
|
26
|
+
content.split("\n").map((line) => _parseTokenLine(line, prop)),
|
|
27
|
+
}
|
|
28
|
+
) as Record<ParsableLanguage, (content: string) => CodeTokenProps<"span">[][]>;
|
|
29
|
+
|
|
30
|
+
// parseTokenLines.javascript(
|
|
31
|
+
// `const FanYu = {
|
|
32
|
+
// name: '范余振富',
|
|
33
|
+
// nickname: '飯魚',
|
|
34
|
+
// age: 19, // <-點看看🤫
|
|
35
|
+
// hobbies: ['寫程式', '繪畫'],
|
|
36
|
+
// skills: ['TypeScript', 'React', 'Python'],
|
|
37
|
+
// } as const;`
|
|
38
|
+
// );
|
package/eslint.config.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import js from "@eslint/js";
|
|
2
|
-
import globals from "globals";
|
|
3
|
-
import tseslint from "typescript-eslint";
|
|
4
|
-
import pluginReact from "eslint-plugin-react";
|
|
5
|
-
import { defineConfig } from "eslint/config";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export default defineConfig([
|
|
9
|
-
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"] },
|
|
10
|
-
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"], languageOptions: { globals: globals.browser } },
|
|
11
|
-
tseslint.configs.recommended,
|
|
12
|
-
pluginReact.configs.flat.recommended,
|
|
13
|
-
]);
|
package/src/types/props.tsx
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { themes } from "../libs";
|
|
2
|
-
import { AsComponentProps, OverrideProps } from "./common";
|
|
3
|
-
/**
|
|
4
|
-
* 用於表示語法高亮中每個 token 的語意分類,對應於 `<CodeToken />` 中的 `type`。
|
|
5
|
-
*
|
|
6
|
-
* 每個類型會對應特定的顏色與用途,例如關鍵字、數字、字串、註解等,
|
|
7
|
-
* 可配合 `codeColoreMap` 指定顯示樣式。s
|
|
8
|
-
*
|
|
9
|
-
* 類型分為以下幾大類:
|
|
10
|
-
*
|
|
11
|
-
* - `keyword1` / `keyword2`: 關鍵字,如 `const`、`return`、`import` 等,分顏色類別。
|
|
12
|
-
* - `string`: 字串常值,如 `'text'`、`"value"`。
|
|
13
|
-
* - `number`: 數字常值,如 `123`、`3.14`。
|
|
14
|
-
* - `comment`: 註解內容,如 `//`。
|
|
15
|
-
* - `type`: 類型定義,如 `interface`、`enum`、`type`。
|
|
16
|
-
* - `variable`: 識別符號,如變數名、函式名、類別名。
|
|
17
|
-
* - `constant`: 常數或靜態值,如 `PI`、`MAX_VALUE`。
|
|
18
|
-
* - `brackets1`, `brackets2`, `brackets3`: 括號配對,區分不同層級的括號。
|
|
19
|
-
* - `operator`: 運算符,如 `=`, `+`, `===`, `<`, `>=`。
|
|
20
|
-
* - `default`: 其他符號,如 `;`, `,`, `.`, `?`, `"`, `'`。
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* const token: CodeTokenType = "keyword1";
|
|
24
|
-
* const token2: CodeTokenType = "string";
|
|
25
|
-
*/
|
|
26
|
-
export type CodeTokenType =
|
|
27
|
-
| `keyword${number}` // 關鍵字,分兩種樣式層級
|
|
28
|
-
| "function" // 函式名
|
|
29
|
-
| "string" // 字串常值:'abc'、"hello"
|
|
30
|
-
| "number" // 數值常量:123、3.14
|
|
31
|
-
| "comment" // 註解內容:// 或 /* */
|
|
32
|
-
| "type" // 類型定義:type、interface、enum
|
|
33
|
-
| "variable" // 變數名、函式名、類別名等識別符號
|
|
34
|
-
| "constant" // 常數值:例如 enum 值、靜態屬性
|
|
35
|
-
| `brackets${number}` // 括號配對,多層不同樣式:(), [], {}
|
|
36
|
-
| "operator" // 運算符號:=、+、*、===、<、>= 等
|
|
37
|
-
| "default"; // 其他符號:, ; . ? ! 等
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 表示可用的語法高亮主題名稱。
|
|
41
|
-
* 對應 `themes` 陣列中定義的名稱,例如 `"vscode-dark"`。
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* const theme: CodeTheme = "vscode-dark";
|
|
45
|
-
*/
|
|
46
|
-
export type CodeTheme = (typeof themes)[number];
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 單一語法 token 的屬性,用於 <CodeToken /> 元件。
|
|
50
|
-
*
|
|
51
|
-
* @template T HTML 或客製元素,例如 span、a、Link 等
|
|
52
|
-
*/
|
|
53
|
-
export type CodeTokenProps<T extends React.ElementType> = AsComponentProps<
|
|
54
|
-
T,
|
|
55
|
-
{
|
|
56
|
-
/**
|
|
57
|
-
* 語法 token 的語意類型,用於指定樣式顏色。
|
|
58
|
-
*/
|
|
59
|
-
type?: CodeTokenType;
|
|
60
|
-
/**
|
|
61
|
-
* 語法主題名稱。
|
|
62
|
-
* @default "vscode-dark"
|
|
63
|
-
*/
|
|
64
|
-
theme?: CodeTheme;
|
|
65
|
-
}
|
|
66
|
-
>;
|
|
67
|
-
|
|
68
|
-
export type CodeTokenBuilder = <T extends React.ElementType>(
|
|
69
|
-
children: CodeTokenProps<T>["children"],
|
|
70
|
-
props?: CodeTokenProps<T>
|
|
71
|
-
) => CodeTokenProps<T>;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 用於單一程式碼行的屬性,用在 <CodeLine /> 或類似元件中。
|
|
75
|
-
*/
|
|
76
|
-
export type CodeLineProps<T extends React.ElementType> = OverrideProps<
|
|
77
|
-
React.HTMLAttributes<HTMLElement>,
|
|
78
|
-
{
|
|
79
|
-
/**
|
|
80
|
-
* 該行所包含的語法 token。
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```tsx
|
|
84
|
-
* <CodeLine tokens={[
|
|
85
|
-
* { type: "keyword-blue", children: "const" },
|
|
86
|
-
* { type: "variable", children: "myVar" },
|
|
87
|
-
* { type: "operator", children: "=" },
|
|
88
|
-
* { type: "string", children: "'Hello'" },
|
|
89
|
-
* ]} />
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
tokens: CodeTokenProps<T>[];
|
|
93
|
-
/**
|
|
94
|
-
* 語法主題名稱。
|
|
95
|
-
* @default "vscode-dark"
|
|
96
|
-
*/
|
|
97
|
-
theme?: CodeTheme;
|
|
98
|
-
}
|
|
99
|
-
>;
|
|
100
|
-
|
|
101
|
-
export type CodeBlockProps<T extends React.ElementType> = OverrideProps<
|
|
102
|
-
React.HTMLAttributes<HTMLPreElement>,
|
|
103
|
-
{
|
|
104
|
-
/**
|
|
105
|
-
* 所有程式碼行的 token 陣列。
|
|
106
|
-
*
|
|
107
|
-
* @example
|
|
108
|
-
* ```tsx
|
|
109
|
-
* <CodeBlock tokenLines={[
|
|
110
|
-
* [
|
|
111
|
-
* { type: "keyword-blue", children: "const" },
|
|
112
|
-
* { type: "variable", children: "x" },
|
|
113
|
-
* { type: "operator", children: "=" },
|
|
114
|
-
* { type: "number", children: "42" },
|
|
115
|
-
* ],
|
|
116
|
-
* [
|
|
117
|
-
* { type: "keyword-purple", children: "return" },
|
|
118
|
-
* { type: "variable", children: "x" },
|
|
119
|
-
* ],
|
|
120
|
-
* ]} />
|
|
121
|
-
* ```
|
|
122
|
-
*/
|
|
123
|
-
tokenLines: CodeTokenProps<T>[][];
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* 是否顯示行號。
|
|
127
|
-
* @default true
|
|
128
|
-
*/
|
|
129
|
-
showLineNumbers?: boolean;
|
|
130
|
-
/**
|
|
131
|
-
* 行號的樣式。
|
|
132
|
-
* @default { color: "#888", fontSize: "0.8em" }
|
|
133
|
-
* @example
|
|
134
|
-
* ```tsx
|
|
135
|
-
* <CodeBlock lineNumberStyle={{ color: "#888", fontSize: "0.8em" }} />
|
|
136
|
-
* ```
|
|
137
|
-
* */
|
|
138
|
-
lineNumberStyle?: React.CSSProperties;
|
|
139
|
-
/**
|
|
140
|
-
* 語法主題名稱。
|
|
141
|
-
* @default "vscode-dark"
|
|
142
|
-
*/
|
|
143
|
-
theme?: CodeTheme;
|
|
144
|
-
}
|
|
145
|
-
>;
|