@xiping/react-components 1.0.43 → 1.0.45
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/cjs/components/shimmer-button/ShimmerButton.js +1 -1
- package/dist/cjs/components/shiny-button/ShinyButton.js +1 -1
- package/dist/cjs/components/sparkles-text/SparklesText.js +1 -1
- package/dist/cjs/components/subtitle-player/SubtitlePlayer.d.ts +30 -0
- package/dist/cjs/components/subtitle-player/SubtitlePlayer.js +3 -0
- package/dist/cjs/components/subtitle-player/index.d.ts +2 -0
- package/dist/cjs/components/txt-editor/TxtEditor.d.ts +5 -4
- package/dist/cjs/components/txt-editor/TxtEditor.js +32 -1
- package/dist/cjs/components/txt-reader/TxtReader.js +1 -1
- package/dist/cjs/components/txt-reader/index.module.css.js +1 -1
- package/dist/cjs/components/variable-proximity/index.d.ts +10 -0
- package/dist/cjs/components/variable-proximity/index.js +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/react-components.css +1 -1
- package/dist/cjs/subtitle/lib/src/parser.js +5 -0
- package/dist/es/components/shimmer-button/ShimmerButton.js +29 -62
- package/dist/es/components/shiny-button/ShinyButton.js +15 -17
- package/dist/es/components/sparkles-text/SparklesText.js +30 -29
- package/dist/es/components/subtitle-player/SubtitlePlayer.d.ts +30 -0
- package/dist/es/components/subtitle-player/SubtitlePlayer.js +103 -0
- package/dist/es/components/subtitle-player/index.d.ts +2 -0
- package/dist/es/components/txt-editor/TxtEditor.d.ts +5 -4
- package/dist/es/components/txt-editor/TxtEditor.js +102 -43
- package/dist/es/components/txt-reader/TxtReader.js +48 -55
- package/dist/es/components/txt-reader/index.module.css.js +6 -2
- package/dist/es/components/variable-proximity/index.d.ts +10 -0
- package/dist/es/components/variable-proximity/index.js +166 -94
- package/dist/es/index.d.ts +1 -0
- package/dist/es/index.js +12 -10
- package/dist/es/react-components.css +1 -1
- package/dist/es/subtitle/lib/src/parser.js +56 -0
- package/package.json +9 -5
|
@@ -1,75 +1,42 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import
|
|
3
|
-
import { cn as
|
|
4
|
-
|
|
1
|
+
import { jsxs as c, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import d from "react";
|
|
3
|
+
import { cn as h } from "../../utils/utils.js";
|
|
4
|
+
/* empty css */
|
|
5
|
+
const l = d.forwardRef(
|
|
5
6
|
({
|
|
6
|
-
shimmerColor:
|
|
7
|
-
shimmerSize:
|
|
8
|
-
shimmerDuration:
|
|
9
|
-
borderRadius:
|
|
10
|
-
background:
|
|
11
|
-
className:
|
|
12
|
-
children:
|
|
13
|
-
...
|
|
14
|
-
},
|
|
7
|
+
shimmerColor: r = "#ffffff",
|
|
8
|
+
shimmerSize: e = "0.05em",
|
|
9
|
+
shimmerDuration: m = "3s",
|
|
10
|
+
borderRadius: s = "100px",
|
|
11
|
+
background: t = "rgba(0, 0, 0, 1)",
|
|
12
|
+
className: a,
|
|
13
|
+
children: o,
|
|
14
|
+
...n
|
|
15
|
+
}, p) => /* @__PURE__ */ c(
|
|
15
16
|
"button",
|
|
16
17
|
{
|
|
17
18
|
style: {
|
|
18
19
|
"--spread": "90deg",
|
|
19
|
-
"--shimmer-color":
|
|
20
|
-
"--radius":
|
|
21
|
-
"--speed":
|
|
22
|
-
"--cut":
|
|
23
|
-
"--bg":
|
|
20
|
+
"--shimmer-color": r,
|
|
21
|
+
"--radius": s,
|
|
22
|
+
"--speed": m,
|
|
23
|
+
"--cut": e,
|
|
24
|
+
"--bg": t
|
|
24
25
|
},
|
|
25
|
-
className:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
n
|
|
29
|
-
),
|
|
30
|
-
ref: u,
|
|
31
|
-
...f,
|
|
26
|
+
className: h("xiping-shimmer-button", a),
|
|
27
|
+
ref: p,
|
|
28
|
+
...n,
|
|
32
29
|
children: [
|
|
33
|
-
/* @__PURE__ */
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"-z-30 blur-[2px]",
|
|
38
|
-
"absolute inset-0 overflow-visible [container-type:size]"
|
|
39
|
-
),
|
|
40
|
-
children: /* @__PURE__ */ r("div", { className: "absolute inset-0 h-[100cqh] animate-shimmer-slide [aspect-ratio:1] [border-radius:0] [mask:none]", children: /* @__PURE__ */ r("div", { className: "absolute -inset-full w-auto rotate-0 animate-spin-around [background:conic-gradient(from_calc(270deg-(var(--spread)*0.5)),transparent_0,var(--shimmer-color)_var(--spread),transparent_var(--spread))] [translate:0_0]" }) })
|
|
41
|
-
}
|
|
42
|
-
),
|
|
43
|
-
d,
|
|
44
|
-
/* @__PURE__ */ r(
|
|
45
|
-
"div",
|
|
46
|
-
{
|
|
47
|
-
className: e(
|
|
48
|
-
"insert-0 absolute size-full",
|
|
49
|
-
"rounded-2xl px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#ffffff1f]",
|
|
50
|
-
// transition
|
|
51
|
-
"transform-gpu transition-all duration-300 ease-in-out",
|
|
52
|
-
// on hover
|
|
53
|
-
"group-hover:shadow-[inset_0_-6px_10px_#ffffff3f]",
|
|
54
|
-
// on click
|
|
55
|
-
"group-active:shadow-[inset_0_-10px_10px_#ffffff3f]"
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
),
|
|
59
|
-
/* @__PURE__ */ r(
|
|
60
|
-
"div",
|
|
61
|
-
{
|
|
62
|
-
className: e(
|
|
63
|
-
"absolute -z-20 [background:var(--bg)] [border-radius:var(--radius)] [inset:var(--cut)]"
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
)
|
|
30
|
+
/* @__PURE__ */ i("div", { className: "xiping-shimmer-button-spark-container", children: /* @__PURE__ */ i("div", { className: "xiping-shimmer-button-spark", children: /* @__PURE__ */ i("div", { className: "xiping-shimmer-button-spark-before" }) }) }),
|
|
31
|
+
o,
|
|
32
|
+
/* @__PURE__ */ i("div", { className: "xiping-shimmer-button-highlight" }),
|
|
33
|
+
/* @__PURE__ */ i("div", { className: "xiping-shimmer-button-backdrop" })
|
|
67
34
|
]
|
|
68
35
|
}
|
|
69
36
|
)
|
|
70
37
|
);
|
|
71
|
-
|
|
38
|
+
l.displayName = "ShimmerButton";
|
|
72
39
|
export {
|
|
73
|
-
|
|
74
|
-
|
|
40
|
+
l as ShimmerButton,
|
|
41
|
+
l as default
|
|
75
42
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as
|
|
2
|
+
import { jsxs as t, jsx as a } from "react/jsx-runtime";
|
|
3
3
|
import { cn as s } from "../../utils/utils.js";
|
|
4
4
|
import { motion as o } from "motion/react";
|
|
5
|
-
import
|
|
6
|
-
|
|
5
|
+
import p from "react";
|
|
6
|
+
/* empty css */
|
|
7
|
+
const c = {
|
|
7
8
|
initial: { "--x": "100%", scale: 0.8 },
|
|
8
9
|
animate: { "--x": "-100%", scale: 1 },
|
|
9
10
|
whileTap: { scale: 0.95 },
|
|
@@ -22,28 +23,25 @@ const p = {
|
|
|
22
23
|
mass: 0.5
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
|
-
},
|
|
26
|
+
}, l = p.forwardRef(({ children: r, className: e, ...n }, i) => /* @__PURE__ */ t(
|
|
26
27
|
o.button,
|
|
27
28
|
{
|
|
28
29
|
ref: i,
|
|
29
|
-
className: s(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
),
|
|
33
|
-
...p,
|
|
34
|
-
...t,
|
|
30
|
+
className: s("xiping-shiny-button", e),
|
|
31
|
+
...c,
|
|
32
|
+
...n,
|
|
35
33
|
children: [
|
|
36
|
-
/* @__PURE__ */
|
|
34
|
+
/* @__PURE__ */ a(
|
|
37
35
|
"span",
|
|
38
36
|
{
|
|
39
|
-
className: "
|
|
37
|
+
className: "xiping-shiny-button-text",
|
|
40
38
|
style: {
|
|
41
39
|
maskImage: "linear-gradient(-75deg,var(--primary) calc(var(--x) + 20%),transparent calc(var(--x) + 30%),var(--primary) calc(var(--x) + 100%))"
|
|
42
40
|
},
|
|
43
|
-
children:
|
|
41
|
+
children: r
|
|
44
42
|
}
|
|
45
43
|
),
|
|
46
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ a(
|
|
47
45
|
"span",
|
|
48
46
|
{
|
|
49
47
|
style: {
|
|
@@ -51,13 +49,13 @@ const p = {
|
|
|
51
49
|
WebkitMask: "linear-gradient(rgb(0,0,0), rgb(0,0,0)) content-box exclude,linear-gradient(rgb(0,0,0), rgb(0,0,0))",
|
|
52
50
|
backgroundImage: "linear-gradient(-75deg,var(--primary)/10% calc(var(--x)+20%),var(--primary)/50% calc(var(--x)+25%),var(--primary)/10% calc(var(--x)+100%))"
|
|
53
51
|
},
|
|
54
|
-
className: "
|
|
52
|
+
className: "xiping-shiny-button-border"
|
|
55
53
|
}
|
|
56
54
|
)
|
|
57
55
|
]
|
|
58
56
|
}
|
|
59
57
|
));
|
|
60
|
-
|
|
58
|
+
l.displayName = "ShinyButton";
|
|
61
59
|
export {
|
|
62
|
-
|
|
60
|
+
l as ShinyButton
|
|
63
61
|
};
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as r, jsxs as
|
|
3
|
-
import { motion as
|
|
4
|
-
import { useState as
|
|
5
|
-
import { cn as
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { jsx as r, jsxs as g } from "react/jsx-runtime";
|
|
3
|
+
import { motion as k } from "motion/react";
|
|
4
|
+
import { useState as L, useEffect as S } from "react";
|
|
5
|
+
import { cn as y } from "../../utils/utils.js";
|
|
6
|
+
/* empty css */
|
|
7
|
+
const M = ({ id: i, x: t, y: o, color: s, delay: c, scale: l }) => /* @__PURE__ */ r(
|
|
8
|
+
k.svg,
|
|
8
9
|
{
|
|
9
|
-
className: "
|
|
10
|
-
initial: { opacity: 0, left: t, top:
|
|
10
|
+
className: "xiping-sparkle",
|
|
11
|
+
initial: { opacity: 0, left: t, top: o },
|
|
11
12
|
animate: {
|
|
12
13
|
opacity: [0, 1, 0],
|
|
13
|
-
scale: [0,
|
|
14
|
+
scale: [0, l, 0],
|
|
14
15
|
rotate: [75, 120, 150]
|
|
15
16
|
},
|
|
16
|
-
transition: { duration: 0.8, repeat: 1 / 0, delay:
|
|
17
|
+
transition: { duration: 0.8, repeat: 1 / 0, delay: c },
|
|
17
18
|
width: "21",
|
|
18
19
|
height: "21",
|
|
19
20
|
viewBox: "0 0 21 21",
|
|
@@ -25,46 +26,46 @@ const $ = ({ id: o, x: t, y: i, color: s, delay: l, scale: c }) => /* @__PURE__
|
|
|
25
26
|
}
|
|
26
27
|
)
|
|
27
28
|
},
|
|
28
|
-
|
|
29
|
-
),
|
|
30
|
-
children:
|
|
29
|
+
i
|
|
30
|
+
), I = ({
|
|
31
|
+
children: i,
|
|
31
32
|
colors: t = { first: "#9E7AFF", second: "#FE8BBB" },
|
|
32
|
-
className:
|
|
33
|
+
className: o,
|
|
33
34
|
sparklesCount: s = 10,
|
|
34
|
-
...
|
|
35
|
+
...c
|
|
35
36
|
}) => {
|
|
36
|
-
const [
|
|
37
|
-
return
|
|
37
|
+
const [l, p] = L([]);
|
|
38
|
+
return S(() => {
|
|
38
39
|
const a = () => {
|
|
39
|
-
const e = `${Math.random() * 100}%`, n = `${Math.random() * 100}%`, h = Math.random() > 0.5 ? t.first : t.second,
|
|
40
|
-
return { id: `${e}-${n}-${Date.now()}`, x: e, y: n, color: h, delay:
|
|
41
|
-
},
|
|
40
|
+
const e = `${Math.random() * 100}%`, n = `${Math.random() * 100}%`, h = Math.random() > 0.5 ? t.first : t.second, x = Math.random() * 2, C = Math.random() * 1 + 0.3, u = Math.random() * 10 + 5;
|
|
41
|
+
return { id: `${e}-${n}-${Date.now()}`, x: e, y: n, color: h, delay: x, scale: C, lifespan: u };
|
|
42
|
+
}, d = () => {
|
|
42
43
|
const e = Array.from({ length: s }, a);
|
|
43
|
-
|
|
44
|
+
p(e);
|
|
44
45
|
}, m = () => {
|
|
45
|
-
|
|
46
|
+
p(
|
|
46
47
|
(e) => e.map((n) => n.lifespan <= 0 ? a() : { ...n, lifespan: n.lifespan - 0.1 })
|
|
47
48
|
);
|
|
48
49
|
};
|
|
49
|
-
|
|
50
|
+
d();
|
|
50
51
|
const f = setInterval(m, 100);
|
|
51
52
|
return () => clearInterval(f);
|
|
52
53
|
}, [t.first, t.second, s]), /* @__PURE__ */ r(
|
|
53
54
|
"div",
|
|
54
55
|
{
|
|
55
|
-
className:
|
|
56
|
-
...
|
|
56
|
+
className: y("xiping-sparkles-text", o),
|
|
57
|
+
...c,
|
|
57
58
|
style: {
|
|
58
59
|
"--sparkles-first-color": `${t.first}`,
|
|
59
60
|
"--sparkles-second-color": `${t.second}`
|
|
60
61
|
},
|
|
61
|
-
children: /* @__PURE__ */
|
|
62
|
-
|
|
63
|
-
/* @__PURE__ */ r("strong", { children:
|
|
62
|
+
children: /* @__PURE__ */ g("span", { className: "xiping-sparkles-text-wrapper", children: [
|
|
63
|
+
l.map((a) => /* @__PURE__ */ r(M, { ...a }, a.id)),
|
|
64
|
+
/* @__PURE__ */ r("strong", { children: i })
|
|
64
65
|
] })
|
|
65
66
|
}
|
|
66
67
|
);
|
|
67
68
|
};
|
|
68
69
|
export {
|
|
69
|
-
|
|
70
|
+
I as SparklesText
|
|
70
71
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type SubtitleType = 'srt' | 'vtt';
|
|
3
|
+
export interface SubtitleData {
|
|
4
|
+
/** 字幕类型 */
|
|
5
|
+
type: SubtitleType;
|
|
6
|
+
/** 字幕内容字符串 */
|
|
7
|
+
content: string;
|
|
8
|
+
/** 可选的语言标识,用于多字幕对照时的标签显示 */
|
|
9
|
+
label?: string;
|
|
10
|
+
}
|
|
11
|
+
export type SubtitleDisplayMode = 'current' | 'lyrics';
|
|
12
|
+
export interface SubtitlePlayerProps {
|
|
13
|
+
/** 字幕数据,可以是单个字幕或多个字幕(用于对照) */
|
|
14
|
+
subtitles: SubtitleData | SubtitleData[];
|
|
15
|
+
/** 当前播放进度(秒数) */
|
|
16
|
+
currentTime: number;
|
|
17
|
+
/** 显示模式:'current' 只显示当前字幕,'lyrics' 显示全部字幕并高亮当前 */
|
|
18
|
+
mode?: SubtitleDisplayMode;
|
|
19
|
+
/** 自定义类名 */
|
|
20
|
+
className?: string;
|
|
21
|
+
/** 自定义样式 */
|
|
22
|
+
style?: React.CSSProperties;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 字幕播放组件
|
|
26
|
+
* 支持 SRT 和 WebVTT 格式,可以同时显示多个字幕进行对照
|
|
27
|
+
* 支持两种显示模式:当前模式(只显示当前字幕)和歌词模式(显示全部并高亮当前)
|
|
28
|
+
*/
|
|
29
|
+
export declare const SubtitlePlayer: React.FC<SubtitlePlayerProps>;
|
|
30
|
+
export default SubtitlePlayer;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as s, jsxs as T } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as N, useMemo as S, useEffect as H } from "react";
|
|
3
|
+
import { parseSRT as $, parseVTT as C } from "../../subtitle/lib/src/parser.js";
|
|
4
|
+
/* empty css */
|
|
5
|
+
function d(i) {
|
|
6
|
+
const r = i.replace(",", ".").split(":");
|
|
7
|
+
if (r.length !== 3)
|
|
8
|
+
return 0;
|
|
9
|
+
const c = parseInt(r[0], 10) || 0, o = parseInt(r[1], 10) || 0, m = parseFloat(r[2]) || 0;
|
|
10
|
+
return c * 3600 + o * 60 + m;
|
|
11
|
+
}
|
|
12
|
+
function E(i, n) {
|
|
13
|
+
for (const r of i) {
|
|
14
|
+
const c = d(r.startTime), o = d(r.endTime);
|
|
15
|
+
if (n >= c && n <= o)
|
|
16
|
+
return r;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const B = ({
|
|
21
|
+
subtitles: i,
|
|
22
|
+
currentTime: n,
|
|
23
|
+
mode: r = "current",
|
|
24
|
+
className: c = "",
|
|
25
|
+
style: o
|
|
26
|
+
}) => {
|
|
27
|
+
const m = Array.isArray(i) ? i : [i], f = N(null), y = N(null), b = S(() => m.map((e) => {
|
|
28
|
+
try {
|
|
29
|
+
return {
|
|
30
|
+
entries: e.type === "srt" ? $(e.content) : C(e.content),
|
|
31
|
+
label: e.label
|
|
32
|
+
};
|
|
33
|
+
} catch (t) {
|
|
34
|
+
return console.error("字幕解析失败:", t), {
|
|
35
|
+
entries: [],
|
|
36
|
+
label: e.label
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}), [m]), h = S(() => b.map(({ entries: e, label: t }) => ({
|
|
40
|
+
entry: E(e, n),
|
|
41
|
+
label: t,
|
|
42
|
+
entries: e
|
|
43
|
+
// 保留所有条目用于歌词模式
|
|
44
|
+
})), [b, n]);
|
|
45
|
+
return H(() => {
|
|
46
|
+
if (r === "lyrics" && y.current && f.current) {
|
|
47
|
+
const e = f.current, t = y.current;
|
|
48
|
+
e.getBoundingClientRect(), t.getBoundingClientRect(), e.scrollTop;
|
|
49
|
+
const l = t.offsetTop, a = e.clientHeight, u = t.clientHeight, p = l - a / 2 + u / 2;
|
|
50
|
+
e.scrollTo({
|
|
51
|
+
top: p,
|
|
52
|
+
behavior: "smooth"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}, [r, n]), r === "current" ? h.some(({ entry: t }) => t !== null) ? /* @__PURE__ */ s(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: `subtitle-player subtitle-player--current ${c}`,
|
|
59
|
+
style: o,
|
|
60
|
+
children: h.map(({ entry: t, label: l }, a) => t ? /* @__PURE__ */ T(
|
|
61
|
+
"div",
|
|
62
|
+
{
|
|
63
|
+
className: "subtitle-player-item",
|
|
64
|
+
"data-label": l || void 0,
|
|
65
|
+
children: [
|
|
66
|
+
l && /* @__PURE__ */ s("span", { className: "subtitle-player-label", children: l }),
|
|
67
|
+
/* @__PURE__ */ s("div", { className: "subtitle-player-text", children: t.text.split(`
|
|
68
|
+
`).map((u, p) => /* @__PURE__ */ s("div", { className: "subtitle-player-line", children: u }, p)) })
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
a
|
|
72
|
+
) : null)
|
|
73
|
+
}
|
|
74
|
+
) : null : /* @__PURE__ */ s(
|
|
75
|
+
"div",
|
|
76
|
+
{
|
|
77
|
+
ref: f,
|
|
78
|
+
className: `subtitle-player subtitle-player--lyrics ${c}`,
|
|
79
|
+
style: o,
|
|
80
|
+
children: b.map(({ entries: e, label: t }, l) => /* @__PURE__ */ T("div", { className: "subtitle-player-group", children: [
|
|
81
|
+
t && /* @__PURE__ */ s("span", { className: "subtitle-player-label", children: t }),
|
|
82
|
+
e.map((a, u) => {
|
|
83
|
+
const p = d(a.startTime), v = d(a.endTime), g = n >= p && n <= v, x = n > v;
|
|
84
|
+
return /* @__PURE__ */ s(
|
|
85
|
+
"div",
|
|
86
|
+
{
|
|
87
|
+
ref: g ? y : null,
|
|
88
|
+
className: `subtitle-player-item ${g ? "subtitle-player-item--active" : ""} ${x ? "subtitle-player-item--past" : ""}`,
|
|
89
|
+
"data-label": t || void 0,
|
|
90
|
+
children: /* @__PURE__ */ s("div", { className: "subtitle-player-text", children: a.text.split(`
|
|
91
|
+
`).map((R, A) => /* @__PURE__ */ s("div", { className: "subtitle-player-line", children: R }, A)) })
|
|
92
|
+
},
|
|
93
|
+
u
|
|
94
|
+
);
|
|
95
|
+
})
|
|
96
|
+
] }, l))
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
export {
|
|
101
|
+
B as SubtitlePlayer,
|
|
102
|
+
B as default
|
|
103
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Editor } from '@tiptap/react';
|
|
2
2
|
export interface TxtEditorProps {
|
|
3
3
|
/**
|
|
4
4
|
* 编辑器高度
|
|
@@ -13,6 +13,7 @@ export interface TxtEditorProps {
|
|
|
13
13
|
/**
|
|
14
14
|
* 编辑器默认语言
|
|
15
15
|
* @default 'plaintext'
|
|
16
|
+
* @deprecated Tiptap 不支持语法高亮,此属性已废弃
|
|
16
17
|
*/
|
|
17
18
|
language?: string;
|
|
18
19
|
/**
|
|
@@ -40,13 +41,13 @@ export interface TxtEditorProps {
|
|
|
40
41
|
/**
|
|
41
42
|
* 编辑器加载完成回调
|
|
42
43
|
*/
|
|
43
|
-
onMount?:
|
|
44
|
+
onMount?: (editor: Editor) => void;
|
|
44
45
|
/**
|
|
45
46
|
* 文本编辑器样式
|
|
46
47
|
*/
|
|
47
48
|
className?: string;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
+
* Tiptap 文本编辑器组件
|
|
51
52
|
*/
|
|
52
|
-
export declare const TxtEditor: ({ height, width, language, defaultValue, value, theme, readOnly, onChange, onMount, className, }: TxtEditorProps) => import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
export declare const TxtEditor: ({ height, width, language: _language, defaultValue, value, theme, readOnly, onChange, onMount, className, }: TxtEditorProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,54 +1,113 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { jsxs as k, jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { useEditor as M, EditorContent as w } from "@tiptap/react";
|
|
3
|
+
import C from "@tiptap/starter-kit";
|
|
4
|
+
import { useMemo as P, useEffect as a } from "react";
|
|
5
|
+
const U = ({
|
|
6
|
+
height: t = "500px",
|
|
7
|
+
width: i = "100%",
|
|
8
|
+
language: y = "plaintext",
|
|
9
|
+
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
10
|
+
defaultValue: d,
|
|
11
|
+
value: o,
|
|
12
|
+
theme: p = "light",
|
|
13
|
+
readOnly: n = !1,
|
|
14
|
+
onChange: m,
|
|
13
15
|
onMount: s,
|
|
14
16
|
className: u
|
|
15
17
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
const l = o !== void 0, g = P(() => d || o || "", [d, o]), e = M({
|
|
19
|
+
extensions: [
|
|
20
|
+
C.configure({
|
|
21
|
+
// 禁用大部分格式化功能,保持纯文本编辑体验
|
|
22
|
+
bold: !1,
|
|
23
|
+
italic: !1,
|
|
24
|
+
strike: !1,
|
|
25
|
+
code: !1,
|
|
26
|
+
heading: !1,
|
|
27
|
+
blockquote: !1,
|
|
28
|
+
horizontalRule: !1,
|
|
29
|
+
hardBreak: !1
|
|
30
|
+
// 保留历史记录、拖拽光标和间隙光标功能(使用默认配置)
|
|
31
|
+
})
|
|
32
|
+
],
|
|
33
|
+
content: g,
|
|
34
|
+
editable: !n,
|
|
35
|
+
immediatelyRender: !1,
|
|
36
|
+
onUpdate: ({ editor: f }) => {
|
|
37
|
+
const b = f.getText();
|
|
38
|
+
m?.(b);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
if (a(() => {
|
|
42
|
+
if (!e || !l) return;
|
|
43
|
+
const f = e.getText();
|
|
44
|
+
o !== f && e.commands.setContent(o || "", { emitUpdate: !1 });
|
|
45
|
+
}, [e, o, l]), a(() => {
|
|
46
|
+
e && e.setEditable(!n);
|
|
47
|
+
}, [e, n]), a(() => {
|
|
48
|
+
e && s && s(e);
|
|
49
|
+
}, [e, s]), !e)
|
|
50
|
+
return null;
|
|
51
|
+
const x = typeof t == "number" ? `${t}px` : t, h = typeof i == "number" ? `${i}px` : i, r = p === "vs-dark";
|
|
52
|
+
return /* @__PURE__ */ k(
|
|
53
|
+
"div",
|
|
19
54
|
{
|
|
20
55
|
className: u,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
f.current = n, s?.(n, p), n.updateOptions({
|
|
29
|
-
minimap: { enabled: !1 },
|
|
30
|
-
// 禁用小地图
|
|
31
|
-
lineNumbers: "on",
|
|
32
|
-
// 显示行号
|
|
33
|
-
roundedSelection: !1,
|
|
34
|
-
// 方形选区
|
|
35
|
-
scrollBeyondLastLine: !1,
|
|
36
|
-
// 禁止滚动到最后一行之后
|
|
37
|
-
readOnly: o,
|
|
38
|
-
// 是否只读
|
|
39
|
-
fontSize: 14
|
|
40
|
-
// 字体大小
|
|
41
|
-
});
|
|
42
|
-
},
|
|
43
|
-
onChange: (n) => {
|
|
44
|
-
d?.(n || "");
|
|
56
|
+
style: {
|
|
57
|
+
width: h,
|
|
58
|
+
height: x,
|
|
59
|
+
border: `1px solid ${r ? "#3e3e3e" : "#d4d4d4"}`,
|
|
60
|
+
borderRadius: "4px",
|
|
61
|
+
overflow: "hidden",
|
|
62
|
+
backgroundColor: r ? "#1e1e1e" : "#ffffff"
|
|
45
63
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
children: [
|
|
65
|
+
/* @__PURE__ */ c(
|
|
66
|
+
w,
|
|
67
|
+
{
|
|
68
|
+
editor: e,
|
|
69
|
+
style: {
|
|
70
|
+
height: "100%",
|
|
71
|
+
overflow: "auto"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
/* @__PURE__ */ c("style", { children: `
|
|
76
|
+
.ProseMirror {
|
|
77
|
+
outline: none;
|
|
78
|
+
padding: 12px;
|
|
79
|
+
min-height: 100%;
|
|
80
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
|
81
|
+
font-size: 14px;
|
|
82
|
+
line-height: 1.5;
|
|
83
|
+
color: ${r ? "#d4d4d4" : "#333333"};
|
|
84
|
+
white-space: pre-wrap;
|
|
85
|
+
word-wrap: break-word;
|
|
86
|
+
}
|
|
87
|
+
.ProseMirror p {
|
|
88
|
+
margin: 0;
|
|
89
|
+
padding: 0;
|
|
90
|
+
}
|
|
91
|
+
.ProseMirror p + p {
|
|
92
|
+
margin-top: 0;
|
|
93
|
+
}
|
|
94
|
+
.ProseMirror:focus {
|
|
95
|
+
outline: none;
|
|
96
|
+
}
|
|
97
|
+
${r ? `
|
|
98
|
+
.ProseMirror {
|
|
99
|
+
background-color: #1e1e1e;
|
|
100
|
+
}
|
|
101
|
+
` : `
|
|
102
|
+
.ProseMirror {
|
|
103
|
+
background-color: #ffffff;
|
|
104
|
+
}
|
|
105
|
+
`}
|
|
106
|
+
` })
|
|
107
|
+
]
|
|
49
108
|
}
|
|
50
109
|
);
|
|
51
110
|
};
|
|
52
111
|
export {
|
|
53
|
-
|
|
112
|
+
U as TxtEditor
|
|
54
113
|
};
|