@whletsgo/editor 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/cjs/HaoRichEditor/index.d.ts +9 -0
- package/dist/cjs/HaoRichEditor/index.js +80 -0
- package/dist/cjs/HaoRichEditor/index.styled.d.ts +5 -0
- package/dist/cjs/HaoRichEditor/index.styled.js +55 -0
- package/dist/cjs/components/menu-bar/index.d.ts +6 -0
- package/dist/cjs/components/menu-bar/index.js +340 -0
- package/dist/cjs/components/menu-bar/index.styled.d.ts +8 -0
- package/dist/cjs/components/menu-bar/index.styled.js +92 -0
- package/dist/cjs/extensions/video/index.d.ts +24 -0
- package/dist/cjs/extensions/video/index.js +116 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +41 -0
- package/dist/esm/HaoRichEditor/index.d.ts +9 -0
- package/dist/esm/HaoRichEditor/index.js +50 -0
- package/dist/esm/HaoRichEditor/index.styled.d.ts +5 -0
- package/dist/esm/HaoRichEditor/index.styled.js +10 -0
- package/dist/esm/components/menu-bar/index.d.ts +6 -0
- package/dist/esm/components/menu-bar/index.js +362 -0
- package/dist/esm/components/menu-bar/index.styled.d.ts +8 -0
- package/dist/esm/components/menu-bar/index.styled.js +31 -0
- package/dist/esm/extensions/video/index.d.ts +24 -0
- package/dist/esm/extensions/video/index.js +129 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 27276971@qq.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
interface HaoRichEditorProps {
|
|
3
|
+
value?: string;
|
|
4
|
+
onChange?: (value: string) => void;
|
|
5
|
+
onUploadImage?: (file: File) => Promise<string>;
|
|
6
|
+
onUploadVideo?: (file: File) => Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
declare const HaoRichEditor: FC<HaoRichEditorProps>;
|
|
9
|
+
export default HaoRichEditor;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/HaoRichEditor/index.tsx
|
|
30
|
+
var HaoRichEditor_exports = {};
|
|
31
|
+
__export(HaoRichEditor_exports, {
|
|
32
|
+
default: () => HaoRichEditor_default
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(HaoRichEditor_exports);
|
|
35
|
+
var import_react = __toESM(require("react"));
|
|
36
|
+
var import_extension_text_style = require("@tiptap/extension-text-style");
|
|
37
|
+
var import_react2 = require("@tiptap/react");
|
|
38
|
+
var import_starter_kit = __toESM(require("@tiptap/starter-kit"));
|
|
39
|
+
var import_extension_image = __toESM(require("@tiptap/extension-image"));
|
|
40
|
+
var import_extension_text_align = __toESM(require("@tiptap/extension-text-align"));
|
|
41
|
+
var import_menu_bar = __toESM(require("../components/menu-bar"));
|
|
42
|
+
var import_video = require("../extensions/video");
|
|
43
|
+
var import_index = require("./index.styled");
|
|
44
|
+
var extensions = [
|
|
45
|
+
import_extension_text_style.TextStyleKit,
|
|
46
|
+
import_starter_kit.default,
|
|
47
|
+
import_extension_image.default,
|
|
48
|
+
import_extension_text_style.TextStyle,
|
|
49
|
+
import_extension_text_style.Color,
|
|
50
|
+
import_extension_text_style.LineHeight,
|
|
51
|
+
import_video.Video,
|
|
52
|
+
import_extension_text_align.default.configure({
|
|
53
|
+
types: ["heading", "paragraph"],
|
|
54
|
+
alignments: ["left", "center", "right"],
|
|
55
|
+
defaultAlignment: "left"
|
|
56
|
+
})
|
|
57
|
+
];
|
|
58
|
+
var HaoRichEditor = ({
|
|
59
|
+
value,
|
|
60
|
+
onChange,
|
|
61
|
+
onUploadImage,
|
|
62
|
+
onUploadVideo
|
|
63
|
+
}) => {
|
|
64
|
+
const editor = (0, import_react2.useEditor)({
|
|
65
|
+
extensions,
|
|
66
|
+
content: value,
|
|
67
|
+
onUpdate: ({ editor: editor2 }) => {
|
|
68
|
+
const html = editor2.getHTML();
|
|
69
|
+
onChange == null ? void 0 : onChange(html);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
(0, import_react.useEffect)(() => {
|
|
73
|
+
if (editor && value !== void 0 && value !== editor.getHTML()) {
|
|
74
|
+
editor.commands.setContent(value);
|
|
75
|
+
}
|
|
76
|
+
}, [value, editor]);
|
|
77
|
+
const providerValue = (0, import_react.useMemo)(() => ({ editor }), [editor]);
|
|
78
|
+
return /* @__PURE__ */ import_react.default.createElement(import_react2.EditorContext.Provider, { value: providerValue }, /* @__PURE__ */ import_react.default.createElement(import_index.HaoRichEditorContainer, null, /* @__PURE__ */ import_react.default.createElement(import_menu_bar.default, { onUploadImage, onUploadVideo }), /* @__PURE__ */ import_react.default.createElement(import_index.HaoRichEditorContent, { editor })));
|
|
79
|
+
};
|
|
80
|
+
var HaoRichEditor_default = HaoRichEditor;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const HaoRichEditorContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
3
|
+
export declare const HaoRichEditorContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<Omit<import("@tiptap/react").EditorContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>, "ref"> & {
|
|
4
|
+
ref?: ((instance: HTMLDivElement | null) => void) | import("react").RefObject<HTMLDivElement> | null | undefined;
|
|
5
|
+
}, never>> & string & Omit<import("react").NamedExoticComponent<Omit<import("@tiptap/react").EditorContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>, keyof import("react").Component<any, {}, any>>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/HaoRichEditor/index.styled.ts
|
|
30
|
+
var index_styled_exports = {};
|
|
31
|
+
__export(index_styled_exports, {
|
|
32
|
+
HaoRichEditorContainer: () => HaoRichEditorContainer,
|
|
33
|
+
HaoRichEditorContent: () => HaoRichEditorContent
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_styled_exports);
|
|
36
|
+
var import_react = require("@tiptap/react");
|
|
37
|
+
var import_styled_components = __toESM(require("styled-components"));
|
|
38
|
+
var HaoRichEditorContainer = import_styled_components.default.div`
|
|
39
|
+
border: 1px solid #e0e0e0;
|
|
40
|
+
border-radius: 8px;
|
|
41
|
+
max-width: inherit;
|
|
42
|
+
width: 100%;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
`;
|
|
45
|
+
var HaoRichEditorContent = (0, import_styled_components.default)(import_react.EditorContent)`
|
|
46
|
+
padding: 0 10px;
|
|
47
|
+
height: 500px;
|
|
48
|
+
overflow-y: auto;
|
|
49
|
+
overflow-x: hidden;
|
|
50
|
+
`;
|
|
51
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
52
|
+
0 && (module.exports = {
|
|
53
|
+
HaoRichEditorContainer,
|
|
54
|
+
HaoRichEditorContent
|
|
55
|
+
});
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/components/menu-bar/index.tsx
|
|
30
|
+
var menu_bar_exports = {};
|
|
31
|
+
__export(menu_bar_exports, {
|
|
32
|
+
default: () => menu_bar_default
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(menu_bar_exports);
|
|
35
|
+
var import_react = __toESM(require("react"));
|
|
36
|
+
var import_react2 = require("@tiptap/react");
|
|
37
|
+
var import_react3 = require("react");
|
|
38
|
+
var import_index = require("./index.styled");
|
|
39
|
+
var MenuBar = ({ onUploadImage, onUploadVideo }) => {
|
|
40
|
+
const { editor } = (0, import_react2.useCurrentEditor)();
|
|
41
|
+
const [uploading, setUploading] = (0, import_react3.useState)(false);
|
|
42
|
+
const editorState = (0, import_react2.useEditorState)({
|
|
43
|
+
editor,
|
|
44
|
+
selector: (ctx) => {
|
|
45
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
46
|
+
return {
|
|
47
|
+
isBold: ((_a = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _a.isActive("bold")) ?? false,
|
|
48
|
+
canBold: ((_b = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _b.can().chain().toggleBold().run()) ?? false,
|
|
49
|
+
isItalic: ((_c = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _c.isActive("italic")) ?? false,
|
|
50
|
+
canItalic: ((_d = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _d.can().chain().toggleItalic().run()) ?? false,
|
|
51
|
+
isStrike: ((_e = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _e.isActive("strike")) ?? false,
|
|
52
|
+
canStrike: ((_f = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _f.can().chain().toggleStrike().run()) ?? false,
|
|
53
|
+
isCode: ((_g = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _g.isActive("code")) ?? false,
|
|
54
|
+
canCode: ((_h = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _h.can().chain().toggleCode().run()) ?? false,
|
|
55
|
+
isParagraph: ((_i = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _i.isActive("paragraph")) ?? false,
|
|
56
|
+
isHeading1: ((_j = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _j.isActive("heading", { level: 1 })) ?? false,
|
|
57
|
+
isHeading2: ((_k = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _k.isActive("heading", { level: 2 })) ?? false,
|
|
58
|
+
isHeading3: ((_l = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _l.isActive("heading", { level: 3 })) ?? false,
|
|
59
|
+
isHeading4: ((_m = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _m.isActive("heading", { level: 4 })) ?? false,
|
|
60
|
+
isHeading5: ((_n = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _n.isActive("heading", { level: 5 })) ?? false,
|
|
61
|
+
isHeading6: ((_o = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _o.isActive("heading", { level: 6 })) ?? false,
|
|
62
|
+
isBulletList: ((_p = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _p.isActive("bulletList")) ?? false,
|
|
63
|
+
isOrderedList: ((_q = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _q.isActive("orderedList")) ?? false,
|
|
64
|
+
isCodeBlock: ((_r = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _r.isActive("codeBlock")) ?? false,
|
|
65
|
+
isBlockquote: ((_s = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _s.isActive("blockquote")) ?? false,
|
|
66
|
+
canUndo: ((_t = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _t.can().chain().undo().run()) ?? false,
|
|
67
|
+
canRedo: ((_u = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _u.can().chain().redo().run()) ?? false,
|
|
68
|
+
isAlignLeft: ((_v = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _v.isActive({ textAlign: "left" })) ?? false,
|
|
69
|
+
isAlignCenter: ((_w = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _w.isActive({ textAlign: "center" })) ?? false,
|
|
70
|
+
isAlignRight: ((_x = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _x.isActive({ textAlign: "right" })) ?? false,
|
|
71
|
+
color: ((_y = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _y.getAttributes("textStyle").color) ?? "",
|
|
72
|
+
isSmall: (_z = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _z.isActive("textStyle", { lineHeight: "1.5" }),
|
|
73
|
+
isLarge: (_A = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _A.isActive("textStyle", { lineHeight: "2.0" }),
|
|
74
|
+
isExtraLarge: (_B = ctx == null ? void 0 : ctx.editor) == null ? void 0 : _B.isActive("textStyle", { lineHeight: "4.0" })
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
const handleImageUpload = async (event) => {
|
|
79
|
+
var _a;
|
|
80
|
+
const file = (_a = event.target.files) == null ? void 0 : _a[0];
|
|
81
|
+
if (!file)
|
|
82
|
+
return;
|
|
83
|
+
if (!file.type.startsWith("image/")) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setUploading(true);
|
|
87
|
+
const formData = new FormData();
|
|
88
|
+
formData.append("file", file);
|
|
89
|
+
try {
|
|
90
|
+
const imageUrl = await (onUploadImage == null ? void 0 : onUploadImage(file));
|
|
91
|
+
editor == null ? void 0 : editor.chain().focus().setImage({ src: imageUrl ?? "" }).run();
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error("图片上传失败:", error);
|
|
94
|
+
} finally {
|
|
95
|
+
setUploading(false);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const handleVideoUpload = async (event) => {
|
|
99
|
+
var _a;
|
|
100
|
+
const file = (_a = event.target.files) == null ? void 0 : _a[0];
|
|
101
|
+
if (!file)
|
|
102
|
+
return;
|
|
103
|
+
if (!file.type.startsWith("video/")) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
setUploading(true);
|
|
107
|
+
try {
|
|
108
|
+
const videoUrl = await (onUploadVideo == null ? void 0 : onUploadVideo(file));
|
|
109
|
+
if (!videoUrl)
|
|
110
|
+
return;
|
|
111
|
+
editor == null ? void 0 : editor.chain().focus().setVideo({ src: videoUrl, controls: true }).run();
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error("视频上传失败:", error);
|
|
114
|
+
} finally {
|
|
115
|
+
setUploading(false);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
return /* @__PURE__ */ import_react.default.createElement(import_index.MenuBarContainer, null, /* @__PURE__ */ import_react.default.createElement(import_index.MenuBarContent, null, /* @__PURE__ */ import_react.default.createElement(
|
|
119
|
+
import_index.MenuBarButton,
|
|
120
|
+
{
|
|
121
|
+
onClick: (e) => {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
editor == null ? void 0 : editor.chain().focus().setParagraph().run();
|
|
124
|
+
},
|
|
125
|
+
isActive: (editorState == null ? void 0 : editorState.isParagraph) ?? false
|
|
126
|
+
},
|
|
127
|
+
"段落"
|
|
128
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
129
|
+
import_index.MenuBarButton,
|
|
130
|
+
{
|
|
131
|
+
onClick: (e) => {
|
|
132
|
+
e.preventDefault();
|
|
133
|
+
editor == null ? void 0 : editor.chain().focus().toggleBold().run();
|
|
134
|
+
},
|
|
135
|
+
disabled: !(editorState == null ? void 0 : editorState.canBold),
|
|
136
|
+
isActive: (editorState == null ? void 0 : editorState.isBold) ?? false
|
|
137
|
+
},
|
|
138
|
+
"加粗"
|
|
139
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
140
|
+
import_index.MenuBarButton,
|
|
141
|
+
{
|
|
142
|
+
onClick: (e) => {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
editor == null ? void 0 : editor.chain().focus().toggleItalic().run();
|
|
145
|
+
},
|
|
146
|
+
isActive: (editorState == null ? void 0 : editorState.isItalic) ?? false
|
|
147
|
+
},
|
|
148
|
+
"斜体"
|
|
149
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
150
|
+
import_index.MenuBarButton,
|
|
151
|
+
{
|
|
152
|
+
onClick: (e) => {
|
|
153
|
+
e.preventDefault();
|
|
154
|
+
editor == null ? void 0 : editor.chain().focus().toggleStrike().run();
|
|
155
|
+
},
|
|
156
|
+
isActive: (editorState == null ? void 0 : editorState.isStrike) ?? false
|
|
157
|
+
},
|
|
158
|
+
"删除线"
|
|
159
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
160
|
+
import_index.MenuBarButton,
|
|
161
|
+
{
|
|
162
|
+
onClick: (e) => {
|
|
163
|
+
e.preventDefault();
|
|
164
|
+
editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 1 }).run();
|
|
165
|
+
},
|
|
166
|
+
isActive: (editorState == null ? void 0 : editorState.isHeading1) ?? false
|
|
167
|
+
},
|
|
168
|
+
"H1"
|
|
169
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
170
|
+
import_index.MenuBarButton,
|
|
171
|
+
{
|
|
172
|
+
onClick: (e) => {
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 2 }).run();
|
|
175
|
+
},
|
|
176
|
+
isActive: (editorState == null ? void 0 : editorState.isHeading2) ?? false
|
|
177
|
+
},
|
|
178
|
+
"H2"
|
|
179
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
180
|
+
import_index.MenuBarButton,
|
|
181
|
+
{
|
|
182
|
+
onClick: (e) => {
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 3 }).run();
|
|
185
|
+
},
|
|
186
|
+
isActive: (editorState == null ? void 0 : editorState.isHeading3) ?? false
|
|
187
|
+
},
|
|
188
|
+
"H3"
|
|
189
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
190
|
+
import_index.MenuBarButton,
|
|
191
|
+
{
|
|
192
|
+
onClick: (e) => {
|
|
193
|
+
e.preventDefault();
|
|
194
|
+
editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 4 }).run();
|
|
195
|
+
},
|
|
196
|
+
isActive: (editorState == null ? void 0 : editorState.isHeading4) ?? false
|
|
197
|
+
},
|
|
198
|
+
"H4"
|
|
199
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
200
|
+
import_index.MenuBarButton,
|
|
201
|
+
{
|
|
202
|
+
onClick: (e) => {
|
|
203
|
+
e.preventDefault();
|
|
204
|
+
editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 5 }).run();
|
|
205
|
+
},
|
|
206
|
+
isActive: (editorState == null ? void 0 : editorState.isHeading5) ?? false
|
|
207
|
+
},
|
|
208
|
+
"H5"
|
|
209
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
210
|
+
import_index.MenuBarButton,
|
|
211
|
+
{
|
|
212
|
+
onClick: (e) => {
|
|
213
|
+
e.preventDefault();
|
|
214
|
+
editor == null ? void 0 : editor.chain().focus().toggleHeading({ level: 6 }).run();
|
|
215
|
+
},
|
|
216
|
+
isActive: (editorState == null ? void 0 : editorState.isHeading6) ?? false
|
|
217
|
+
},
|
|
218
|
+
"H6"
|
|
219
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
220
|
+
import_index.MenuBarButton,
|
|
221
|
+
{
|
|
222
|
+
onClick: (e) => {
|
|
223
|
+
e.preventDefault();
|
|
224
|
+
editor == null ? void 0 : editor.chain().focus().setTextAlign("left").run();
|
|
225
|
+
},
|
|
226
|
+
isActive: (editorState == null ? void 0 : editorState.isAlignLeft) ?? false
|
|
227
|
+
},
|
|
228
|
+
"左对齐"
|
|
229
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
230
|
+
import_index.MenuBarButton,
|
|
231
|
+
{
|
|
232
|
+
onClick: (e) => {
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
editor == null ? void 0 : editor.chain().focus().setTextAlign("center").run();
|
|
235
|
+
},
|
|
236
|
+
isActive: (editorState == null ? void 0 : editorState.isAlignCenter) ?? false
|
|
237
|
+
},
|
|
238
|
+
"居中"
|
|
239
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
240
|
+
import_index.MenuBarButton,
|
|
241
|
+
{
|
|
242
|
+
onClick: (e) => {
|
|
243
|
+
e.preventDefault();
|
|
244
|
+
editor == null ? void 0 : editor.chain().focus().setTextAlign("right").run();
|
|
245
|
+
},
|
|
246
|
+
isActive: (editorState == null ? void 0 : editorState.isAlignRight) ?? false
|
|
247
|
+
},
|
|
248
|
+
"右对齐"
|
|
249
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
250
|
+
import_index.MenuBarButton,
|
|
251
|
+
{
|
|
252
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleTextStyle({ lineHeight: "1.5" }).run(),
|
|
253
|
+
isActive: (editorState == null ? void 0 : editorState.isSmall) ?? false
|
|
254
|
+
},
|
|
255
|
+
"行高1.5"
|
|
256
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
257
|
+
import_index.MenuBarButton,
|
|
258
|
+
{
|
|
259
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleTextStyle({ lineHeight: "2.0" }).run(),
|
|
260
|
+
isActive: (editorState == null ? void 0 : editorState.isLarge) ?? false
|
|
261
|
+
},
|
|
262
|
+
"行高2.0"
|
|
263
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
264
|
+
import_index.MenuBarButton,
|
|
265
|
+
{
|
|
266
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().toggleTextStyle({ lineHeight: "4.0" }).run(),
|
|
267
|
+
isActive: (editorState == null ? void 0 : editorState.isExtraLarge) ?? false
|
|
268
|
+
},
|
|
269
|
+
"行高4.0"
|
|
270
|
+
), /* @__PURE__ */ import_react.default.createElement(import_index.MenuBarButton, { onClick: () => editor == null ? void 0 : editor.chain().focus().unsetLineHeight().run() }, "取消行高"), /* @__PURE__ */ import_react.default.createElement(
|
|
271
|
+
import_index.MenuBarButton,
|
|
272
|
+
{
|
|
273
|
+
onClick: (e) => {
|
|
274
|
+
e.preventDefault();
|
|
275
|
+
editor == null ? void 0 : editor.chain().focus().toggleBulletList().run();
|
|
276
|
+
},
|
|
277
|
+
isActive: (editorState == null ? void 0 : editorState.isBulletList) ?? false
|
|
278
|
+
},
|
|
279
|
+
"列表"
|
|
280
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
281
|
+
import_index.MenuBarButton,
|
|
282
|
+
{
|
|
283
|
+
onClick: (e) => {
|
|
284
|
+
e.preventDefault();
|
|
285
|
+
editor == null ? void 0 : editor.chain().focus().toggleOrderedList().run();
|
|
286
|
+
},
|
|
287
|
+
isActive: (editorState == null ? void 0 : editorState.isOrderedList) ?? false
|
|
288
|
+
},
|
|
289
|
+
"有序列表"
|
|
290
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
291
|
+
import_index.MenuBarButton,
|
|
292
|
+
{
|
|
293
|
+
onClick: (e) => {
|
|
294
|
+
e.preventDefault();
|
|
295
|
+
editor == null ? void 0 : editor.chain().focus().toggleCodeBlock().run();
|
|
296
|
+
},
|
|
297
|
+
isActive: (editorState == null ? void 0 : editorState.isCodeBlock) ?? false
|
|
298
|
+
},
|
|
299
|
+
"代码段"
|
|
300
|
+
), /* @__PURE__ */ import_react.default.createElement(
|
|
301
|
+
import_index.MenuBarButton,
|
|
302
|
+
{
|
|
303
|
+
onClick: (e) => {
|
|
304
|
+
e.preventDefault();
|
|
305
|
+
editor == null ? void 0 : editor.chain().focus().toggleBlockquote().run();
|
|
306
|
+
},
|
|
307
|
+
isActive: (editorState == null ? void 0 : editorState.isBlockquote) ?? false
|
|
308
|
+
},
|
|
309
|
+
"引用"
|
|
310
|
+
), /* @__PURE__ */ import_react.default.createElement(import_index.MenuBarButton, { disabled: uploading }, uploading ? "上传中..." : "图片", /* @__PURE__ */ import_react.default.createElement(
|
|
311
|
+
import_index.MenuBarInput,
|
|
312
|
+
{
|
|
313
|
+
type: "file",
|
|
314
|
+
accept: "image/*",
|
|
315
|
+
onChange: handleImageUpload
|
|
316
|
+
}
|
|
317
|
+
)), /* @__PURE__ */ import_react.default.createElement(import_index.MenuBarButton, { disabled: uploading }, uploading ? "上传中..." : "视频", /* @__PURE__ */ import_react.default.createElement(
|
|
318
|
+
import_index.MenuBarInput,
|
|
319
|
+
{
|
|
320
|
+
type: "file",
|
|
321
|
+
accept: "video/*",
|
|
322
|
+
onChange: handleVideoUpload
|
|
323
|
+
}
|
|
324
|
+
)), /* @__PURE__ */ import_react.default.createElement(
|
|
325
|
+
import_index.MenuBarColorInput,
|
|
326
|
+
{
|
|
327
|
+
type: "color",
|
|
328
|
+
value: (editorState == null ? void 0 : editorState.color) ?? "",
|
|
329
|
+
onInput: (event) => editor == null ? void 0 : editor.chain().focus().setColor(event.currentTarget.value).run()
|
|
330
|
+
}
|
|
331
|
+
), /* @__PURE__ */ import_react.default.createElement(import_index.MenuBarButton, { onClick: () => editor == null ? void 0 : editor.chain().focus().undo().run(), disabled: !(editorState == null ? void 0 : editorState.canUndo) }, "撤销"), /* @__PURE__ */ import_react.default.createElement(
|
|
332
|
+
import_index.MenuBarButton,
|
|
333
|
+
{
|
|
334
|
+
onClick: () => editor == null ? void 0 : editor.chain().focus().redo().run(),
|
|
335
|
+
disabled: !(editorState == null ? void 0 : editorState.canRedo)
|
|
336
|
+
},
|
|
337
|
+
"重做"
|
|
338
|
+
)));
|
|
339
|
+
};
|
|
340
|
+
var menu_bar_default = MenuBar;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const MenuBarContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
3
|
+
export declare const MenuBarContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
4
|
+
export declare const MenuBarButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {
|
|
5
|
+
isActive?: boolean | undefined;
|
|
6
|
+
}>> & string;
|
|
7
|
+
export declare const MenuBarInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
|
|
8
|
+
export declare const MenuBarColorInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/components/menu-bar/index.styled.ts
|
|
30
|
+
var index_styled_exports = {};
|
|
31
|
+
__export(index_styled_exports, {
|
|
32
|
+
MenuBarButton: () => MenuBarButton,
|
|
33
|
+
MenuBarColorInput: () => MenuBarColorInput,
|
|
34
|
+
MenuBarContainer: () => MenuBarContainer,
|
|
35
|
+
MenuBarContent: () => MenuBarContent,
|
|
36
|
+
MenuBarInput: () => MenuBarInput
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(index_styled_exports);
|
|
39
|
+
var import_styled_components = __toESM(require("styled-components"));
|
|
40
|
+
var MenuBarContainer = import_styled_components.default.div`
|
|
41
|
+
position: sticky;
|
|
42
|
+
top: 0;
|
|
43
|
+
background-color: #fff;
|
|
44
|
+
z-index: 10;
|
|
45
|
+
border-bottom: 1px solid #e0e0e0;
|
|
46
|
+
padding: 0 10px;
|
|
47
|
+
`;
|
|
48
|
+
var MenuBarContent = import_styled_components.default.div`
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-wrap: wrap;
|
|
51
|
+
gap: 10px;
|
|
52
|
+
padding: 10px 0;
|
|
53
|
+
`;
|
|
54
|
+
var MenuBarButton = import_styled_components.default.button`
|
|
55
|
+
position: relative;
|
|
56
|
+
background-color: ${(props) => props.isActive ? "#6a00f5" : "#f0f0f0"};
|
|
57
|
+
padding: 6px 10px;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
border-radius: 8px;
|
|
60
|
+
border: none;
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
color:${(props) => props.isActive ? "#fff" : "#110F0E"};
|
|
63
|
+
line-height: 1.5;
|
|
64
|
+
transition: background-color 0.3s ease;
|
|
65
|
+
user-select: none;
|
|
66
|
+
&:hover {
|
|
67
|
+
background-color: ${(props) => props.isActive ? "#6a00f5" : "#dadada"};
|
|
68
|
+
}
|
|
69
|
+
&:active{
|
|
70
|
+
background-color: ${(props) => props.isActive ? "#5500c5" : "#bbb"};
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
var MenuBarInput = import_styled_components.default.input`
|
|
74
|
+
position: absolute;
|
|
75
|
+
opacity: 0;
|
|
76
|
+
inset: 0;
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
`;
|
|
79
|
+
var MenuBarColorInput = import_styled_components.default.input`
|
|
80
|
+
padding: 6px 10px;
|
|
81
|
+
display: block;
|
|
82
|
+
border-radius: 8px;
|
|
83
|
+
border: none;
|
|
84
|
+
`;
|
|
85
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
86
|
+
0 && (module.exports = {
|
|
87
|
+
MenuBarButton,
|
|
88
|
+
MenuBarColorInput,
|
|
89
|
+
MenuBarContainer,
|
|
90
|
+
MenuBarContent,
|
|
91
|
+
MenuBarInput
|
|
92
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Node } from '@tiptap/core';
|
|
2
|
+
export interface VideoAttributes {
|
|
3
|
+
src: string;
|
|
4
|
+
controls?: boolean;
|
|
5
|
+
autoplay?: boolean;
|
|
6
|
+
loop?: boolean;
|
|
7
|
+
muted?: boolean;
|
|
8
|
+
playsInline?: boolean;
|
|
9
|
+
poster?: string | null;
|
|
10
|
+
preload?: 'auto' | 'metadata' | 'none' | '';
|
|
11
|
+
width?: string | number | null;
|
|
12
|
+
height?: string | number | null;
|
|
13
|
+
}
|
|
14
|
+
export interface VideoOptions {
|
|
15
|
+
HTMLAttributes: Record<string, any>;
|
|
16
|
+
}
|
|
17
|
+
declare module '@tiptap/core' {
|
|
18
|
+
interface Commands<ReturnType> {
|
|
19
|
+
video: {
|
|
20
|
+
setVideo: (options: VideoAttributes) => ReturnType;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export declare const Video: Node<VideoOptions, any>;
|