@mdaemon/html-editor-react 1.0.1 → 1.0.3
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/index.d.ts +0 -167
- package/dist/index.js +18 -38
- package/dist/index.mjs +18 -38
- package/package.json +13 -4
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,168 +1 @@
|
|
|
1
|
-
import { EditorConfig } from '@mdaemon/html-editor';
|
|
2
|
-
import { EditorEvents } from '@mdaemon/html-editor';
|
|
3
|
-
import { fontNames } from '@mdaemon/html-editor';
|
|
4
|
-
import { ForwardRefExoticComponent } from 'react';
|
|
5
|
-
import { HTMLEditor } from '@mdaemon/html-editor';
|
|
6
|
-
import { RefAttributes } from 'react';
|
|
7
|
-
import { setGetFileSrc } from '@mdaemon/html-editor';
|
|
8
|
-
import { setTranslate } from '@mdaemon/html-editor';
|
|
9
|
-
import { Template } from '@mdaemon/html-editor';
|
|
10
|
-
import { ToolbarButtonAPI } from '@mdaemon/html-editor';
|
|
11
|
-
import { ToolbarButtonSpec } from '@mdaemon/html-editor';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* MDHTMLEditor React Component
|
|
15
|
-
*/
|
|
16
|
-
declare const Editor: ForwardRefExoticComponent<EditorProps & RefAttributes<EditorRef>>;
|
|
17
|
-
export { Editor }
|
|
18
|
-
export { Editor as MDEditor }
|
|
19
|
-
|
|
20
|
-
export { EditorConfig }
|
|
21
|
-
|
|
22
|
-
export { EditorEvents }
|
|
23
|
-
|
|
24
|
-
export declare interface EditorProps {
|
|
25
|
-
/**
|
|
26
|
-
* Editor configuration - TinyMCE compatible
|
|
27
|
-
*/
|
|
28
|
-
config: EditorConfig;
|
|
29
|
-
/**
|
|
30
|
-
* Initial HTML content (also known as 'body' for TinyMCE compat)
|
|
31
|
-
*/
|
|
32
|
-
body?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Initial HTML content (alias for body)
|
|
35
|
-
*/
|
|
36
|
-
initialValue?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Name attribute for the hidden textarea
|
|
39
|
-
*/
|
|
40
|
-
name?: string;
|
|
41
|
-
/**
|
|
42
|
-
* Called when content is modified
|
|
43
|
-
*/
|
|
44
|
-
onDirty?: (dirty: boolean) => void;
|
|
45
|
-
/**
|
|
46
|
-
* Called on content change (debounced)
|
|
47
|
-
*/
|
|
48
|
-
onChange?: (content: string) => void;
|
|
49
|
-
/**
|
|
50
|
-
* Called when editor is fully initialized
|
|
51
|
-
*/
|
|
52
|
-
onInit?: (editor: HTMLEditor) => void;
|
|
53
|
-
/**
|
|
54
|
-
* Called when editor receives focus
|
|
55
|
-
*/
|
|
56
|
-
onFocus?: () => void;
|
|
57
|
-
/**
|
|
58
|
-
* Called when editor loses focus
|
|
59
|
-
*/
|
|
60
|
-
onBlur?: () => void;
|
|
61
|
-
/**
|
|
62
|
-
* Translation function
|
|
63
|
-
*/
|
|
64
|
-
translate?: (key: string) => string;
|
|
65
|
-
/**
|
|
66
|
-
* Function to resolve file paths (like TinyMCE's tinymceScriptSrc path)
|
|
67
|
-
*/
|
|
68
|
-
getFileSrc?: (path: string) => string;
|
|
69
|
-
/**
|
|
70
|
-
* Disable the editor
|
|
71
|
-
*/
|
|
72
|
-
disabled?: boolean;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export declare interface EditorRef {
|
|
76
|
-
/**
|
|
77
|
-
* Get the underlying HTMLEditor instance
|
|
78
|
-
*/
|
|
79
|
-
getEditor: () => HTMLEditor | null;
|
|
80
|
-
/**
|
|
81
|
-
* Get the editor content as HTML
|
|
82
|
-
*/
|
|
83
|
-
getContent: () => string;
|
|
84
|
-
/**
|
|
85
|
-
* Set the editor content
|
|
86
|
-
*/
|
|
87
|
-
setContent: (html: string) => void;
|
|
88
|
-
/**
|
|
89
|
-
* Insert content at cursor position
|
|
90
|
-
*/
|
|
91
|
-
insertContent: (html: string) => void;
|
|
92
|
-
/**
|
|
93
|
-
* Focus the editor
|
|
94
|
-
*/
|
|
95
|
-
focus: () => void;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export { fontNames }
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Get content from the global editor instance
|
|
102
|
-
* Note: Only works with single editor on the page
|
|
103
|
-
*/
|
|
104
|
-
export declare function getEditorContent(): string;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Set content on the global editor instance
|
|
108
|
-
* Note: Only works with single editor on the page
|
|
109
|
-
*/
|
|
110
|
-
export declare function setEditorContent(html: string): void;
|
|
111
|
-
|
|
112
|
-
export { setGetFileSrc }
|
|
113
|
-
|
|
114
|
-
export { setTranslate }
|
|
115
|
-
|
|
116
|
-
export { Template }
|
|
117
|
-
|
|
118
|
-
export { ToolbarButtonAPI }
|
|
119
|
-
|
|
120
|
-
export { ToolbarButtonSpec }
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Hook for programmatic editor control
|
|
124
|
-
*/
|
|
125
|
-
export declare function useEditor(options?: UseEditorOptions): UseEditorReturn;
|
|
126
|
-
|
|
127
|
-
export declare interface UseEditorOptions {
|
|
128
|
-
config?: EditorConfig;
|
|
129
|
-
content?: string;
|
|
130
|
-
onUpdate?: (html: string) => void;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export declare interface UseEditorReturn {
|
|
134
|
-
/**
|
|
135
|
-
* The editor instance
|
|
136
|
-
*/
|
|
137
|
-
editor: HTMLEditor | null;
|
|
138
|
-
/**
|
|
139
|
-
* Ref to attach to the container element
|
|
140
|
-
*/
|
|
141
|
-
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
142
|
-
/**
|
|
143
|
-
* Whether the editor is ready
|
|
144
|
-
*/
|
|
145
|
-
ready: boolean;
|
|
146
|
-
/**
|
|
147
|
-
* Get the current HTML content
|
|
148
|
-
*/
|
|
149
|
-
getContent: () => string;
|
|
150
|
-
/**
|
|
151
|
-
* Set the HTML content
|
|
152
|
-
*/
|
|
153
|
-
setContent: (html: string) => void;
|
|
154
|
-
/**
|
|
155
|
-
* Insert HTML at cursor
|
|
156
|
-
*/
|
|
157
|
-
insertContent: (html: string) => void;
|
|
158
|
-
/**
|
|
159
|
-
* Focus the editor
|
|
160
|
-
*/
|
|
161
|
-
focus: () => void;
|
|
162
|
-
/**
|
|
163
|
-
* Check if editor is dirty
|
|
164
|
-
*/
|
|
165
|
-
isDirty: () => boolean;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
1
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -5,13 +5,12 @@ const react = require("react");
|
|
|
5
5
|
const htmlEditor = require("@mdaemon/html-editor");
|
|
6
6
|
let globalEditor = null;
|
|
7
7
|
function getEditorContent() {
|
|
8
|
-
return
|
|
8
|
+
return globalEditor?.getContent() ?? "";
|
|
9
9
|
}
|
|
10
10
|
function setEditorContent(html) {
|
|
11
|
-
globalEditor
|
|
11
|
+
globalEditor?.setContent(html);
|
|
12
12
|
}
|
|
13
13
|
const Editor = react.forwardRef(function Editor2(props, ref) {
|
|
14
|
-
var _a;
|
|
15
14
|
const {
|
|
16
15
|
config,
|
|
17
16
|
body,
|
|
@@ -45,8 +44,7 @@ const Editor = react.forwardRef(function Editor2(props, ref) {
|
|
|
45
44
|
...config,
|
|
46
45
|
// Pass setup through to allow custom buttons
|
|
47
46
|
setup: (ed) => {
|
|
48
|
-
|
|
49
|
-
(_a2 = config.setup) == null ? void 0 : _a2.call(config, ed);
|
|
47
|
+
config.setup?.(ed);
|
|
50
48
|
}
|
|
51
49
|
});
|
|
52
50
|
editorRef.current = editor;
|
|
@@ -57,20 +55,20 @@ const Editor = react.forwardRef(function Editor2(props, ref) {
|
|
|
57
55
|
}
|
|
58
56
|
editor.on("init", () => {
|
|
59
57
|
setReady(true);
|
|
60
|
-
onInit
|
|
58
|
+
onInit?.(editor);
|
|
61
59
|
});
|
|
62
60
|
editor.on("dirty", (dirty) => {
|
|
63
|
-
onDirty
|
|
61
|
+
onDirty?.(dirty);
|
|
64
62
|
});
|
|
65
63
|
editor.on("change", (content2) => {
|
|
66
|
-
onChange
|
|
64
|
+
onChange?.(content2);
|
|
67
65
|
editor.setDirty(false);
|
|
68
66
|
});
|
|
69
67
|
editor.on("focus", () => {
|
|
70
|
-
onFocus
|
|
68
|
+
onFocus?.();
|
|
71
69
|
});
|
|
72
70
|
editor.on("blur", () => {
|
|
73
|
-
onBlur
|
|
71
|
+
onBlur?.();
|
|
74
72
|
});
|
|
75
73
|
return () => {
|
|
76
74
|
editor.destroy();
|
|
@@ -88,22 +86,10 @@ const Editor = react.forwardRef(function Editor2(props, ref) {
|
|
|
88
86
|
}, [disabled]);
|
|
89
87
|
react.useImperativeHandle(ref, () => ({
|
|
90
88
|
getEditor: () => editorRef.current,
|
|
91
|
-
getContent: () =>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
setContent: (html) => {
|
|
96
|
-
var _a2;
|
|
97
|
-
return (_a2 = editorRef.current) == null ? void 0 : _a2.setContent(html);
|
|
98
|
-
},
|
|
99
|
-
insertContent: (html) => {
|
|
100
|
-
var _a2;
|
|
101
|
-
return (_a2 = editorRef.current) == null ? void 0 : _a2.insertContent(html);
|
|
102
|
-
},
|
|
103
|
-
focus: () => {
|
|
104
|
-
var _a2;
|
|
105
|
-
return (_a2 = editorRef.current) == null ? void 0 : _a2.focus();
|
|
106
|
-
}
|
|
89
|
+
getContent: () => editorRef.current?.getContent() ?? "",
|
|
90
|
+
setContent: (html) => editorRef.current?.setContent(html),
|
|
91
|
+
insertContent: (html) => editorRef.current?.insertContent(html),
|
|
92
|
+
focus: () => editorRef.current?.focus()
|
|
107
93
|
}), []);
|
|
108
94
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md-editor-react-wrapper", children: [
|
|
109
95
|
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "md-editor-container" }),
|
|
@@ -112,7 +98,7 @@ const Editor = react.forwardRef(function Editor2(props, ref) {
|
|
|
112
98
|
{
|
|
113
99
|
type: "hidden",
|
|
114
100
|
name,
|
|
115
|
-
value:
|
|
101
|
+
value: editorRef.current?.getContent() ?? ""
|
|
116
102
|
}
|
|
117
103
|
)
|
|
118
104
|
] });
|
|
@@ -143,24 +129,19 @@ function useEditor(options = {}) {
|
|
|
143
129
|
};
|
|
144
130
|
}, []);
|
|
145
131
|
const getContent = react.useCallback(() => {
|
|
146
|
-
|
|
147
|
-
return ((_a = editorRef.current) == null ? void 0 : _a.getContent()) ?? "";
|
|
132
|
+
return editorRef.current?.getContent() ?? "";
|
|
148
133
|
}, []);
|
|
149
134
|
const setContent = react.useCallback((html) => {
|
|
150
|
-
|
|
151
|
-
(_a = editorRef.current) == null ? void 0 : _a.setContent(html);
|
|
135
|
+
editorRef.current?.setContent(html);
|
|
152
136
|
}, []);
|
|
153
137
|
const insertContent = react.useCallback((html) => {
|
|
154
|
-
|
|
155
|
-
(_a = editorRef.current) == null ? void 0 : _a.insertContent(html);
|
|
138
|
+
editorRef.current?.insertContent(html);
|
|
156
139
|
}, []);
|
|
157
140
|
const focus = react.useCallback(() => {
|
|
158
|
-
|
|
159
|
-
(_a = editorRef.current) == null ? void 0 : _a.focus();
|
|
141
|
+
editorRef.current?.focus();
|
|
160
142
|
}, []);
|
|
161
143
|
const isDirty = react.useCallback(() => {
|
|
162
|
-
|
|
163
|
-
return ((_a = editorRef.current) == null ? void 0 : _a.isDirty()) ?? false;
|
|
144
|
+
return editorRef.current?.isDirty() ?? false;
|
|
164
145
|
}, []);
|
|
165
146
|
return {
|
|
166
147
|
editor: editorRef.current,
|
|
@@ -190,4 +171,3 @@ exports.MDEditor = Editor;
|
|
|
190
171
|
exports.getEditorContent = getEditorContent;
|
|
191
172
|
exports.setEditorContent = setEditorContent;
|
|
192
173
|
exports.useEditor = useEditor;
|
|
193
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -4,13 +4,12 @@ import { setTranslate, setGetFileSrc, HTMLEditor } from "@mdaemon/html-editor";
|
|
|
4
4
|
import { fontNames, setGetFileSrc as setGetFileSrc2, setTranslate as setTranslate2 } from "@mdaemon/html-editor";
|
|
5
5
|
let globalEditor = null;
|
|
6
6
|
function getEditorContent() {
|
|
7
|
-
return
|
|
7
|
+
return globalEditor?.getContent() ?? "";
|
|
8
8
|
}
|
|
9
9
|
function setEditorContent(html) {
|
|
10
|
-
globalEditor
|
|
10
|
+
globalEditor?.setContent(html);
|
|
11
11
|
}
|
|
12
12
|
const Editor = forwardRef(function Editor2(props, ref) {
|
|
13
|
-
var _a;
|
|
14
13
|
const {
|
|
15
14
|
config,
|
|
16
15
|
body,
|
|
@@ -44,8 +43,7 @@ const Editor = forwardRef(function Editor2(props, ref) {
|
|
|
44
43
|
...config,
|
|
45
44
|
// Pass setup through to allow custom buttons
|
|
46
45
|
setup: (ed) => {
|
|
47
|
-
|
|
48
|
-
(_a2 = config.setup) == null ? void 0 : _a2.call(config, ed);
|
|
46
|
+
config.setup?.(ed);
|
|
49
47
|
}
|
|
50
48
|
});
|
|
51
49
|
editorRef.current = editor;
|
|
@@ -56,20 +54,20 @@ const Editor = forwardRef(function Editor2(props, ref) {
|
|
|
56
54
|
}
|
|
57
55
|
editor.on("init", () => {
|
|
58
56
|
setReady(true);
|
|
59
|
-
onInit
|
|
57
|
+
onInit?.(editor);
|
|
60
58
|
});
|
|
61
59
|
editor.on("dirty", (dirty) => {
|
|
62
|
-
onDirty
|
|
60
|
+
onDirty?.(dirty);
|
|
63
61
|
});
|
|
64
62
|
editor.on("change", (content2) => {
|
|
65
|
-
onChange
|
|
63
|
+
onChange?.(content2);
|
|
66
64
|
editor.setDirty(false);
|
|
67
65
|
});
|
|
68
66
|
editor.on("focus", () => {
|
|
69
|
-
onFocus
|
|
67
|
+
onFocus?.();
|
|
70
68
|
});
|
|
71
69
|
editor.on("blur", () => {
|
|
72
|
-
onBlur
|
|
70
|
+
onBlur?.();
|
|
73
71
|
});
|
|
74
72
|
return () => {
|
|
75
73
|
editor.destroy();
|
|
@@ -87,22 +85,10 @@ const Editor = forwardRef(function Editor2(props, ref) {
|
|
|
87
85
|
}, [disabled]);
|
|
88
86
|
useImperativeHandle(ref, () => ({
|
|
89
87
|
getEditor: () => editorRef.current,
|
|
90
|
-
getContent: () =>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
setContent: (html) => {
|
|
95
|
-
var _a2;
|
|
96
|
-
return (_a2 = editorRef.current) == null ? void 0 : _a2.setContent(html);
|
|
97
|
-
},
|
|
98
|
-
insertContent: (html) => {
|
|
99
|
-
var _a2;
|
|
100
|
-
return (_a2 = editorRef.current) == null ? void 0 : _a2.insertContent(html);
|
|
101
|
-
},
|
|
102
|
-
focus: () => {
|
|
103
|
-
var _a2;
|
|
104
|
-
return (_a2 = editorRef.current) == null ? void 0 : _a2.focus();
|
|
105
|
-
}
|
|
88
|
+
getContent: () => editorRef.current?.getContent() ?? "",
|
|
89
|
+
setContent: (html) => editorRef.current?.setContent(html),
|
|
90
|
+
insertContent: (html) => editorRef.current?.insertContent(html),
|
|
91
|
+
focus: () => editorRef.current?.focus()
|
|
106
92
|
}), []);
|
|
107
93
|
return /* @__PURE__ */ jsxs("div", { className: "md-editor-react-wrapper", children: [
|
|
108
94
|
/* @__PURE__ */ jsx("div", { ref: containerRef, className: "md-editor-container" }),
|
|
@@ -111,7 +97,7 @@ const Editor = forwardRef(function Editor2(props, ref) {
|
|
|
111
97
|
{
|
|
112
98
|
type: "hidden",
|
|
113
99
|
name,
|
|
114
|
-
value:
|
|
100
|
+
value: editorRef.current?.getContent() ?? ""
|
|
115
101
|
}
|
|
116
102
|
)
|
|
117
103
|
] });
|
|
@@ -142,24 +128,19 @@ function useEditor(options = {}) {
|
|
|
142
128
|
};
|
|
143
129
|
}, []);
|
|
144
130
|
const getContent = useCallback(() => {
|
|
145
|
-
|
|
146
|
-
return ((_a = editorRef.current) == null ? void 0 : _a.getContent()) ?? "";
|
|
131
|
+
return editorRef.current?.getContent() ?? "";
|
|
147
132
|
}, []);
|
|
148
133
|
const setContent = useCallback((html) => {
|
|
149
|
-
|
|
150
|
-
(_a = editorRef.current) == null ? void 0 : _a.setContent(html);
|
|
134
|
+
editorRef.current?.setContent(html);
|
|
151
135
|
}, []);
|
|
152
136
|
const insertContent = useCallback((html) => {
|
|
153
|
-
|
|
154
|
-
(_a = editorRef.current) == null ? void 0 : _a.insertContent(html);
|
|
137
|
+
editorRef.current?.insertContent(html);
|
|
155
138
|
}, []);
|
|
156
139
|
const focus = useCallback(() => {
|
|
157
|
-
|
|
158
|
-
(_a = editorRef.current) == null ? void 0 : _a.focus();
|
|
140
|
+
editorRef.current?.focus();
|
|
159
141
|
}, []);
|
|
160
142
|
const isDirty = useCallback(() => {
|
|
161
|
-
|
|
162
|
-
return ((_a = editorRef.current) == null ? void 0 : _a.isDirty()) ?? false;
|
|
143
|
+
return editorRef.current?.isDirty() ?? false;
|
|
163
144
|
}, []);
|
|
164
145
|
return {
|
|
165
146
|
editor: editorRef.current,
|
|
@@ -182,4 +163,3 @@ export {
|
|
|
182
163
|
setTranslate2 as setTranslate,
|
|
183
164
|
useEditor
|
|
184
165
|
};
|
|
185
|
-
//# sourceMappingURL=index.mjs.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdaemon/html-editor-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "React wrapper for MDHTMLEditor",
|
|
5
|
+
"homepage": "https://github.com/mdaemon-technologies/MDHTMLEditor-react",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/mdaemon-technologies/MDHTMLEditor-react.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/mdaemon-technologies/MDHTMLEditor-react/issues"
|
|
12
|
+
},
|
|
5
13
|
"main": "dist/index.js",
|
|
6
14
|
"module": "dist/index.mjs",
|
|
7
15
|
"types": "dist/index.d.ts",
|
|
@@ -19,8 +27,9 @@
|
|
|
19
27
|
"dist"
|
|
20
28
|
],
|
|
21
29
|
"scripts": {
|
|
22
|
-
"build": "vite build",
|
|
23
|
-
"dev": "vite build --
|
|
30
|
+
"build": "vite build --mode production",
|
|
31
|
+
"build:dev": "vite build --mode development",
|
|
32
|
+
"dev": "vite build --watch --mode development",
|
|
24
33
|
"demo": "vite serve --config vite.demo.config.ts",
|
|
25
34
|
"test": "jest",
|
|
26
35
|
"test:coverage": "jest --coverage",
|
|
@@ -47,7 +56,7 @@
|
|
|
47
56
|
"@tiptap/react": "^3.19.0"
|
|
48
57
|
},
|
|
49
58
|
"devDependencies": {
|
|
50
|
-
"@mdaemon/html-editor": "^1.0.
|
|
59
|
+
"@mdaemon/html-editor": "^1.0.12",
|
|
51
60
|
"@swc/core": "^1.11.0",
|
|
52
61
|
"@swc/jest": "^0.2.39",
|
|
53
62
|
"@testing-library/jest-dom": "^6.9.1",
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/Editor.tsx","../src/useEditor.ts"],"sourcesContent":["/**\r\n * MDHTMLEditor React Component\r\n * A TinyMCE-compatible React wrapper for MDHTMLEditor\r\n */\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useState,\r\n useImperativeHandle,\r\n forwardRef,\r\n} from 'react';\r\nimport {\r\n HTMLEditor,\r\n EditorConfig,\r\n setTranslate,\r\n setGetFileSrc,\r\n} from '@mdaemon/html-editor';\r\n\r\nexport interface EditorProps {\r\n /**\r\n * Editor configuration - TinyMCE compatible\r\n */\r\n config: EditorConfig;\r\n \r\n /**\r\n * Initial HTML content (also known as 'body' for TinyMCE compat)\r\n */\r\n body?: string;\r\n \r\n /**\r\n * Initial HTML content (alias for body)\r\n */\r\n initialValue?: string;\r\n \r\n /**\r\n * Name attribute for the hidden textarea\r\n */\r\n name?: string;\r\n \r\n /**\r\n * Called when content is modified\r\n */\r\n onDirty?: (dirty: boolean) => void;\r\n \r\n /**\r\n * Called on content change (debounced)\r\n */\r\n onChange?: (content: string) => void;\r\n \r\n /**\r\n * Called when editor is fully initialized\r\n */\r\n onInit?: (editor: HTMLEditor) => void;\r\n \r\n /**\r\n * Called when editor receives focus\r\n */\r\n onFocus?: () => void;\r\n \r\n /**\r\n * Called when editor loses focus\r\n */\r\n onBlur?: () => void;\r\n \r\n /**\r\n * Translation function\r\n */\r\n translate?: (key: string) => string;\r\n \r\n /**\r\n * Function to resolve file paths (like TinyMCE's tinymceScriptSrc path)\r\n */\r\n getFileSrc?: (path: string) => string;\r\n \r\n /**\r\n * Disable the editor\r\n */\r\n disabled?: boolean;\r\n}\r\n\r\nexport interface EditorRef {\r\n /**\r\n * Get the underlying HTMLEditor instance\r\n */\r\n getEditor: () => HTMLEditor | null;\r\n \r\n /**\r\n * Get the editor content as HTML\r\n */\r\n getContent: () => string;\r\n \r\n /**\r\n * Set the editor content\r\n */\r\n setContent: (html: string) => void;\r\n \r\n /**\r\n * Insert content at cursor position\r\n */\r\n insertContent: (html: string) => void;\r\n \r\n /**\r\n * Focus the editor\r\n */\r\n focus: () => void;\r\n}\r\n\r\n// Global editor instance for single-editor APIs\r\nlet globalEditor: HTMLEditor | null = null;\r\n\r\n/**\r\n * Get content from the global editor instance\r\n * Note: Only works with single editor on the page\r\n */\r\nexport function getEditorContent(): string {\r\n return globalEditor?.getContent() ?? '';\r\n}\r\n\r\n/**\r\n * Set content on the global editor instance\r\n * Note: Only works with single editor on the page\r\n */\r\nexport function setEditorContent(html: string): void {\r\n globalEditor?.setContent(html);\r\n}\r\n\r\n/**\r\n * MDHTMLEditor React Component\r\n */\r\nexport const Editor = forwardRef<EditorRef, EditorProps>(function Editor(\r\n props,\r\n ref\r\n) {\r\n const {\r\n config,\r\n body,\r\n initialValue,\r\n name,\r\n onDirty,\r\n onChange,\r\n onInit,\r\n onFocus,\r\n onBlur,\r\n translate,\r\n getFileSrc,\r\n disabled,\r\n } = props;\r\n \r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const editorRef = useRef<HTMLEditor | null>(null);\r\n const [ready, setReady] = useState(false);\r\n \r\n // Set global translation function if provided\r\n useEffect(() => {\r\n if (translate) {\r\n setTranslate(translate);\r\n }\r\n }, [translate]);\r\n \r\n // Set global file source resolver if provided\r\n useEffect(() => {\r\n if (getFileSrc) {\r\n setGetFileSrc(getFileSrc);\r\n }\r\n }, [getFileSrc]);\r\n \r\n // Initialize editor\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n \r\n // Create the editor\r\n const editor = new HTMLEditor(containerRef.current, {\r\n ...config,\r\n // Pass setup through to allow custom buttons\r\n setup: (ed) => {\r\n config.setup?.(ed);\r\n },\r\n });\r\n \r\n editorRef.current = editor;\r\n globalEditor = editor;\r\n \r\n // Set initial content\r\n const content = body ?? initialValue ?? '';\r\n if (content) {\r\n editor.setContent(content);\r\n }\r\n \r\n // Bind events\r\n editor.on('init', () => {\r\n setReady(true);\r\n onInit?.(editor);\r\n });\r\n \r\n editor.on('dirty', (dirty) => {\r\n onDirty?.(dirty);\r\n });\r\n \r\n editor.on('change', (content) => {\r\n onChange?.(content);\r\n editor.setDirty(false);\r\n });\r\n \r\n editor.on('focus', () => {\r\n onFocus?.();\r\n });\r\n \r\n editor.on('blur', () => {\r\n onBlur?.();\r\n });\r\n \r\n // Cleanup\r\n return () => {\r\n editor.destroy();\r\n editorRef.current = null;\r\n if (globalEditor === editor) {\r\n globalEditor = null;\r\n }\r\n };\r\n }, []); // Only run once on mount\r\n \r\n // Update disabled state\r\n useEffect(() => {\r\n // Note: TipTap has setEditable() but our wrapper would need to expose it\r\n // For now, we apply a visual disabled state\r\n if (containerRef.current) {\r\n containerRef.current.style.pointerEvents = disabled ? 'none' : '';\r\n containerRef.current.style.opacity = disabled ? '0.6' : '';\r\n }\r\n }, [disabled]);\r\n \r\n // Expose methods via ref\r\n useImperativeHandle(ref, () => ({\r\n getEditor: () => editorRef.current,\r\n getContent: () => editorRef.current?.getContent() ?? '',\r\n setContent: (html: string) => editorRef.current?.setContent(html),\r\n insertContent: (html: string) => editorRef.current?.insertContent(html),\r\n focus: () => editorRef.current?.focus(),\r\n }), []);\r\n \r\n return (\r\n <div className=\"md-editor-react-wrapper\">\r\n <div ref={containerRef} className=\"md-editor-container\" />\r\n {/* Hidden textarea for form submission */}\r\n {name && ready && (\r\n <input\r\n type=\"hidden\"\r\n name={name}\r\n value={editorRef.current?.getContent() ?? ''}\r\n />\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\nEditor.displayName = 'MDHTMLEditor';\r\n\r\nexport default Editor;\r\n","/**\r\n * useEditor Hook\r\n * Custom hook for advanced editor usage\r\n */\r\n\r\nimport { useEffect, useRef, useState, useCallback } from 'react';\r\nimport { HTMLEditor, EditorConfig } from '@mdaemon/html-editor';\r\n\r\nexport interface UseEditorOptions {\r\n config?: EditorConfig;\r\n content?: string;\r\n onUpdate?: (html: string) => void;\r\n}\r\n\r\nexport interface UseEditorReturn {\r\n /**\r\n * The editor instance\r\n */\r\n editor: HTMLEditor | null;\r\n \r\n /**\r\n * Ref to attach to the container element\r\n */\r\n containerRef: React.RefObject<HTMLDivElement | null>;\r\n \r\n /**\r\n * Whether the editor is ready\r\n */\r\n ready: boolean;\r\n \r\n /**\r\n * Get the current HTML content\r\n */\r\n getContent: () => string;\r\n \r\n /**\r\n * Set the HTML content\r\n */\r\n setContent: (html: string) => void;\r\n \r\n /**\r\n * Insert HTML at cursor\r\n */\r\n insertContent: (html: string) => void;\r\n \r\n /**\r\n * Focus the editor\r\n */\r\n focus: () => void;\r\n \r\n /**\r\n * Check if editor is dirty\r\n */\r\n isDirty: () => boolean;\r\n}\r\n\r\n/**\r\n * Hook for programmatic editor control\r\n */\r\nexport function useEditor(options: UseEditorOptions = {}): UseEditorReturn {\r\n const { config = {}, content = '', onUpdate } = options;\r\n \r\n const containerRef = useRef<HTMLDivElement | null>(null);\r\n const editorRef = useRef<HTMLEditor | null>(null);\r\n const [ready, setReady] = useState(false);\r\n \r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n \r\n const editor = new HTMLEditor(containerRef.current, config);\r\n editorRef.current = editor;\r\n \r\n if (content) {\r\n editor.setContent(content);\r\n }\r\n \r\n editor.on('init', () => {\r\n setReady(true);\r\n });\r\n \r\n if (onUpdate) {\r\n editor.on('change', onUpdate);\r\n }\r\n \r\n return () => {\r\n editor.destroy();\r\n editorRef.current = null;\r\n setReady(false);\r\n };\r\n }, []); // Only mount once\r\n \r\n const getContent = useCallback(() => {\r\n return editorRef.current?.getContent() ?? '';\r\n }, []);\r\n \r\n const setContent = useCallback((html: string) => {\r\n editorRef.current?.setContent(html);\r\n }, []);\r\n \r\n const insertContent = useCallback((html: string) => {\r\n editorRef.current?.insertContent(html);\r\n }, []);\r\n \r\n const focus = useCallback(() => {\r\n editorRef.current?.focus();\r\n }, []);\r\n \r\n const isDirty = useCallback(() => {\r\n return editorRef.current?.isDirty() ?? false;\r\n }, []);\r\n \r\n return {\r\n editor: editorRef.current,\r\n containerRef,\r\n ready,\r\n getContent,\r\n setContent,\r\n insertContent,\r\n focus,\r\n isDirty,\r\n };\r\n}\r\n"],"names":["forwardRef","Editor","useRef","useState","useEffect","setTranslate","setGetFileSrc","HTMLEditor","_a","content","useImperativeHandle","jsxs","jsx","useCallback"],"mappings":"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"}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/Editor.tsx","../src/useEditor.ts"],"sourcesContent":["/**\r\n * MDHTMLEditor React Component\r\n * A TinyMCE-compatible React wrapper for MDHTMLEditor\r\n */\r\n\r\nimport {\r\n useEffect,\r\n useRef,\r\n useState,\r\n useImperativeHandle,\r\n forwardRef,\r\n} from 'react';\r\nimport {\r\n HTMLEditor,\r\n EditorConfig,\r\n setTranslate,\r\n setGetFileSrc,\r\n} from '@mdaemon/html-editor';\r\n\r\nexport interface EditorProps {\r\n /**\r\n * Editor configuration - TinyMCE compatible\r\n */\r\n config: EditorConfig;\r\n \r\n /**\r\n * Initial HTML content (also known as 'body' for TinyMCE compat)\r\n */\r\n body?: string;\r\n \r\n /**\r\n * Initial HTML content (alias for body)\r\n */\r\n initialValue?: string;\r\n \r\n /**\r\n * Name attribute for the hidden textarea\r\n */\r\n name?: string;\r\n \r\n /**\r\n * Called when content is modified\r\n */\r\n onDirty?: (dirty: boolean) => void;\r\n \r\n /**\r\n * Called on content change (debounced)\r\n */\r\n onChange?: (content: string) => void;\r\n \r\n /**\r\n * Called when editor is fully initialized\r\n */\r\n onInit?: (editor: HTMLEditor) => void;\r\n \r\n /**\r\n * Called when editor receives focus\r\n */\r\n onFocus?: () => void;\r\n \r\n /**\r\n * Called when editor loses focus\r\n */\r\n onBlur?: () => void;\r\n \r\n /**\r\n * Translation function\r\n */\r\n translate?: (key: string) => string;\r\n \r\n /**\r\n * Function to resolve file paths (like TinyMCE's tinymceScriptSrc path)\r\n */\r\n getFileSrc?: (path: string) => string;\r\n \r\n /**\r\n * Disable the editor\r\n */\r\n disabled?: boolean;\r\n}\r\n\r\nexport interface EditorRef {\r\n /**\r\n * Get the underlying HTMLEditor instance\r\n */\r\n getEditor: () => HTMLEditor | null;\r\n \r\n /**\r\n * Get the editor content as HTML\r\n */\r\n getContent: () => string;\r\n \r\n /**\r\n * Set the editor content\r\n */\r\n setContent: (html: string) => void;\r\n \r\n /**\r\n * Insert content at cursor position\r\n */\r\n insertContent: (html: string) => void;\r\n \r\n /**\r\n * Focus the editor\r\n */\r\n focus: () => void;\r\n}\r\n\r\n// Global editor instance for single-editor APIs\r\nlet globalEditor: HTMLEditor | null = null;\r\n\r\n/**\r\n * Get content from the global editor instance\r\n * Note: Only works with single editor on the page\r\n */\r\nexport function getEditorContent(): string {\r\n return globalEditor?.getContent() ?? '';\r\n}\r\n\r\n/**\r\n * Set content on the global editor instance\r\n * Note: Only works with single editor on the page\r\n */\r\nexport function setEditorContent(html: string): void {\r\n globalEditor?.setContent(html);\r\n}\r\n\r\n/**\r\n * MDHTMLEditor React Component\r\n */\r\nexport const Editor = forwardRef<EditorRef, EditorProps>(function Editor(\r\n props,\r\n ref\r\n) {\r\n const {\r\n config,\r\n body,\r\n initialValue,\r\n name,\r\n onDirty,\r\n onChange,\r\n onInit,\r\n onFocus,\r\n onBlur,\r\n translate,\r\n getFileSrc,\r\n disabled,\r\n } = props;\r\n \r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const editorRef = useRef<HTMLEditor | null>(null);\r\n const [ready, setReady] = useState(false);\r\n \r\n // Set global translation function if provided\r\n useEffect(() => {\r\n if (translate) {\r\n setTranslate(translate);\r\n }\r\n }, [translate]);\r\n \r\n // Set global file source resolver if provided\r\n useEffect(() => {\r\n if (getFileSrc) {\r\n setGetFileSrc(getFileSrc);\r\n }\r\n }, [getFileSrc]);\r\n \r\n // Initialize editor\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n \r\n // Create the editor\r\n const editor = new HTMLEditor(containerRef.current, {\r\n ...config,\r\n // Pass setup through to allow custom buttons\r\n setup: (ed) => {\r\n config.setup?.(ed);\r\n },\r\n });\r\n \r\n editorRef.current = editor;\r\n globalEditor = editor;\r\n \r\n // Set initial content\r\n const content = body ?? initialValue ?? '';\r\n if (content) {\r\n editor.setContent(content);\r\n }\r\n \r\n // Bind events\r\n editor.on('init', () => {\r\n setReady(true);\r\n onInit?.(editor);\r\n });\r\n \r\n editor.on('dirty', (dirty) => {\r\n onDirty?.(dirty);\r\n });\r\n \r\n editor.on('change', (content) => {\r\n onChange?.(content);\r\n editor.setDirty(false);\r\n });\r\n \r\n editor.on('focus', () => {\r\n onFocus?.();\r\n });\r\n \r\n editor.on('blur', () => {\r\n onBlur?.();\r\n });\r\n \r\n // Cleanup\r\n return () => {\r\n editor.destroy();\r\n editorRef.current = null;\r\n if (globalEditor === editor) {\r\n globalEditor = null;\r\n }\r\n };\r\n }, []); // Only run once on mount\r\n \r\n // Update disabled state\r\n useEffect(() => {\r\n // Note: TipTap has setEditable() but our wrapper would need to expose it\r\n // For now, we apply a visual disabled state\r\n if (containerRef.current) {\r\n containerRef.current.style.pointerEvents = disabled ? 'none' : '';\r\n containerRef.current.style.opacity = disabled ? '0.6' : '';\r\n }\r\n }, [disabled]);\r\n \r\n // Expose methods via ref\r\n useImperativeHandle(ref, () => ({\r\n getEditor: () => editorRef.current,\r\n getContent: () => editorRef.current?.getContent() ?? '',\r\n setContent: (html: string) => editorRef.current?.setContent(html),\r\n insertContent: (html: string) => editorRef.current?.insertContent(html),\r\n focus: () => editorRef.current?.focus(),\r\n }), []);\r\n \r\n return (\r\n <div className=\"md-editor-react-wrapper\">\r\n <div ref={containerRef} className=\"md-editor-container\" />\r\n {/* Hidden textarea for form submission */}\r\n {name && ready && (\r\n <input\r\n type=\"hidden\"\r\n name={name}\r\n value={editorRef.current?.getContent() ?? ''}\r\n />\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\nEditor.displayName = 'MDHTMLEditor';\r\n\r\nexport default Editor;\r\n","/**\r\n * useEditor Hook\r\n * Custom hook for advanced editor usage\r\n */\r\n\r\nimport { useEffect, useRef, useState, useCallback } from 'react';\r\nimport { HTMLEditor, EditorConfig } from '@mdaemon/html-editor';\r\n\r\nexport interface UseEditorOptions {\r\n config?: EditorConfig;\r\n content?: string;\r\n onUpdate?: (html: string) => void;\r\n}\r\n\r\nexport interface UseEditorReturn {\r\n /**\r\n * The editor instance\r\n */\r\n editor: HTMLEditor | null;\r\n \r\n /**\r\n * Ref to attach to the container element\r\n */\r\n containerRef: React.RefObject<HTMLDivElement | null>;\r\n \r\n /**\r\n * Whether the editor is ready\r\n */\r\n ready: boolean;\r\n \r\n /**\r\n * Get the current HTML content\r\n */\r\n getContent: () => string;\r\n \r\n /**\r\n * Set the HTML content\r\n */\r\n setContent: (html: string) => void;\r\n \r\n /**\r\n * Insert HTML at cursor\r\n */\r\n insertContent: (html: string) => void;\r\n \r\n /**\r\n * Focus the editor\r\n */\r\n focus: () => void;\r\n \r\n /**\r\n * Check if editor is dirty\r\n */\r\n isDirty: () => boolean;\r\n}\r\n\r\n/**\r\n * Hook for programmatic editor control\r\n */\r\nexport function useEditor(options: UseEditorOptions = {}): UseEditorReturn {\r\n const { config = {}, content = '', onUpdate } = options;\r\n \r\n const containerRef = useRef<HTMLDivElement | null>(null);\r\n const editorRef = useRef<HTMLEditor | null>(null);\r\n const [ready, setReady] = useState(false);\r\n \r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n \r\n const editor = new HTMLEditor(containerRef.current, config);\r\n editorRef.current = editor;\r\n \r\n if (content) {\r\n editor.setContent(content);\r\n }\r\n \r\n editor.on('init', () => {\r\n setReady(true);\r\n });\r\n \r\n if (onUpdate) {\r\n editor.on('change', onUpdate);\r\n }\r\n \r\n return () => {\r\n editor.destroy();\r\n editorRef.current = null;\r\n setReady(false);\r\n };\r\n }, []); // Only mount once\r\n \r\n const getContent = useCallback(() => {\r\n return editorRef.current?.getContent() ?? '';\r\n }, []);\r\n \r\n const setContent = useCallback((html: string) => {\r\n editorRef.current?.setContent(html);\r\n }, []);\r\n \r\n const insertContent = useCallback((html: string) => {\r\n editorRef.current?.insertContent(html);\r\n }, []);\r\n \r\n const focus = useCallback(() => {\r\n editorRef.current?.focus();\r\n }, []);\r\n \r\n const isDirty = useCallback(() => {\r\n return editorRef.current?.isDirty() ?? false;\r\n }, []);\r\n \r\n return {\r\n editor: editorRef.current,\r\n containerRef,\r\n ready,\r\n getContent,\r\n setContent,\r\n insertContent,\r\n focus,\r\n isDirty,\r\n };\r\n}\r\n"],"names":["Editor","_a","content"],"mappings":"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"}
|