@mbs-dev/react-editor 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/README.md CHANGED
@@ -1 +1,139 @@
1
- # react-editor
1
+
2
+ # @mbs-dev/react-editor
3
+
4
+ A lightweight, typed React wrapper around **Jodit** rich-text editor, designed for real-world CRUD forms (blogs, products, CMS pages, etc.).
5
+
6
+ It provides:
7
+
8
+ - A **simple React component** `<ReactEditor />`
9
+ - A reusable **`config()` helper** for configuration
10
+ - An optional **`uploaderConfig()` helper** to handle image uploads and automatic insertion into the editor
11
+
12
+ ---
13
+
14
+ [![npm version](https://img.shields.io/npm/v/@mbs-dev/react-editor.svg)](https://www.npmjs.com/package/@mbs-dev/react-editor)
15
+ [![npm downloads](https://img.shields.io/npm/dm/@mbs-dev/react-editor.svg)](https://www.npmjs.com/package/@mbs-dev/react-editor)
16
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@mbs-dev/react-editor.svg)](https://bundlephobia.com/package/@mbs-dev/react-editor)
17
+
18
+ ---
19
+
20
+ ## ✨ Features
21
+
22
+ - 🧩 **Simple React API**: controlled `value` + `onChange`
23
+ - βš™οΈ **Helper config**: `config()` to quickly build configuration
24
+ - πŸ–ΌοΈ **Image upload integration**: optional `uploaderConfig()` for file uploading + auto-insert `<img />`
25
+ - πŸ§ͺ **TypeScript-ready**: ships with types & TSX-friendly usage
26
+ - 🧱 **Library-friendly**: minimal surface area, built to be reused across apps
27
+
28
+ ---
29
+
30
+ ## πŸ“¦ Installation
31
+
32
+ ```bash
33
+ npm install @mbs-dev/react-editor
34
+ ```
35
+
36
+ ---
37
+
38
+ ## πŸš€ Quick Start
39
+
40
+ ```tsx
41
+ import React, { useMemo, useState } from 'react';
42
+ import ReactEditor, { config } from '@mbs-dev/react-editor';
43
+
44
+ const MyPage = () => {
45
+ const [content, setContent] = useState('');
46
+
47
+ const editorConfig = useMemo(() => config(false), []);
48
+
49
+ return (
50
+ <ReactEditor
51
+ config={editorConfig}
52
+ value={content}
53
+ onChange={(value) => setContent(value)}
54
+ />
55
+ );
56
+ };
57
+ ```
58
+
59
+ ---
60
+
61
+ ## πŸ”§ Configuration Helpers
62
+
63
+ ### `config(includeUploader?: boolean, apiUrl?: string, imageUrl?: string)`
64
+
65
+ ### `uploaderConfig(apiUrl?: string, imageUrl?: string)`
66
+
67
+ Both helpers simplify setting up configuration and upload support.
68
+
69
+ ---
70
+
71
+ ## 🧩 Symfony API Platform Example (Recommended Integration)
72
+
73
+ If your backend is **Symfony + API Platform**, here is the **most common real‑world setup**:
74
+
75
+ ### **πŸ“Œ 1. Expose your upload endpoint**
76
+
77
+ In your Symfony API (`config/routes.yaml`):
78
+
79
+ ```yaml
80
+ upload_image:
81
+ path: /upload
82
+ controller: App\Controller\ImageUploadController
83
+ methods: [POST]
84
+ ```
85
+
86
+ ### **πŸ“Œ 2. Store uploaded images in `/public/uploads/images`**
87
+
88
+ ```php
89
+ // App/Controller/ImageUploadController.php
90
+
91
+ public function __invoke(Request $request): JsonResponse
92
+ {
93
+ $files = $request->files->get('files');
94
+ $storedFiles = [];
95
+
96
+ foreach ($files as $file) {
97
+ $newName = uniqid().'.'.$file->guessExtension();
98
+ $file->move($this->getParameter('kernel.project_dir').'/public/uploads/images', $newName);
99
+ $storedFiles[] = $newName;
100
+ }
101
+
102
+ return new JsonResponse([
103
+ 'success' => true,
104
+ 'data' => [
105
+ 'files' => $storedFiles,
106
+ 'messages' => [],
107
+ ],
108
+ 'msg' => 'Upload successful'
109
+ ]);
110
+ }
111
+ ```
112
+
113
+ ### **πŸ“Œ 3. Front-end React configuration**
114
+
115
+ ```ts
116
+ export const uploadUrl = `${apiUrl}/upload`;
117
+ export const blogPostImgUrl = `${uploadUrl}/images`;
118
+
119
+ const editorConfig = useMemo(
120
+ () => config(
121
+ true, // enable uploader
122
+ `${apiUrl}/upload`, // Symfony upload endpoint
123
+ blogPostImgUrl // URL to access public images
124
+ ),
125
+ []
126
+ );
127
+ ```
128
+
129
+ This will automatically insert images as:
130
+
131
+ ```html
132
+ <img src="https://your-domain.com/uploads/images/filename.webp" />
133
+ ```
134
+
135
+ ---
136
+
137
+ ## πŸ“ License
138
+
139
+ MIT β€” feel free to use it in commercial and private applications.
package/dist/Editor.js ADDED
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.config = exports.uploaderConfig = void 0;
7
+ var react_1 = __importDefault(require("react"));
8
+ var jodit_react_1 = __importDefault(require("jodit-react"));
9
+ var ReactEditor = function (_a) {
10
+ var onChange = _a.onChange, onBlur = _a.onBlur, value = _a.value, config = _a.config;
11
+ return (react_1.default.createElement(jodit_react_1.default, { value: value, config: config, onBlur: onBlur, onChange: onChange }));
12
+ };
13
+ var uploaderConfig = function (apiUrl, imageUrl) { return ({
14
+ imagesExtensions: ['jpg', 'png', 'jpeg', 'gif', 'webp'],
15
+ filesVariableName: function (t) {
16
+ return 'files[' + t + ']';
17
+ },
18
+ url: apiUrl,
19
+ withCredentials: false,
20
+ format: 'json',
21
+ method: 'POST',
22
+ prepareData: function (formdata) {
23
+ return formdata;
24
+ },
25
+ isSuccess: function (e) {
26
+ var fn = this.jodit;
27
+ if (e.data.files && e.data.files.length) {
28
+ var tagName_1 = 'img';
29
+ e.data.files.forEach(function (filename, index) {
30
+ var elm = fn.createInside.element(tagName_1);
31
+ elm.setAttribute('src', "".concat(imageUrl, "/").concat(filename));
32
+ fn.s.insertImage(elm, null, fn.o.imageDefaultWidth);
33
+ });
34
+ }
35
+ return e.success;
36
+ },
37
+ getMessage: function (e) {
38
+ return e.data.messages && Array.isArray(e.data.messages)
39
+ ? e.data.messages.join('')
40
+ : '';
41
+ },
42
+ process: function (resp) {
43
+ var files = [];
44
+ files.unshift(resp.data);
45
+ return {
46
+ files: resp.data,
47
+ error: resp.msg,
48
+ msg: resp.msg,
49
+ };
50
+ },
51
+ error: function (e) {
52
+ this.j.e.fire('errorMessage', e.message, 'error', 4000);
53
+ },
54
+ defaultHandlerError: function (e) {
55
+ this.j.e.fire('errorMessage', e.message);
56
+ },
57
+ }); };
58
+ exports.uploaderConfig = uploaderConfig;
59
+ var config = function (includeUploader, apiUrl, imageUrl) { return ({
60
+ readonly: false,
61
+ placeholder: 'Start typing...',
62
+ toolbarAdaptive: false,
63
+ useSearch: false,
64
+ language: "en",
65
+ allowResizeX: false,
66
+ allowResizeY: false,
67
+ height: 400,
68
+ enableDragAndDropFileToEditor: true,
69
+ showCharsCounter: true,
70
+ showWordsCounter: true,
71
+ showXPathInStatusbar: false,
72
+ buttons: [
73
+ 'source',
74
+ '|',
75
+ 'bold',
76
+ 'italic',
77
+ 'underline',
78
+ '|',
79
+ 'ul',
80
+ 'ol',
81
+ '|',
82
+ 'image',
83
+ '|',
84
+ 'video',
85
+ '|',
86
+ 'link',
87
+ '|',
88
+ 'undo',
89
+ 'redo',
90
+ '|',
91
+ 'hr',
92
+ '|',
93
+ 'eraser',
94
+ '|',
95
+ 'font',
96
+ 'fontsize',
97
+ 'paragraph',
98
+ 'brush',
99
+ '|',
100
+ 'table',
101
+ 'fullsize',
102
+ ],
103
+ uploader: includeUploader ? (0, exports.uploaderConfig)(apiUrl, imageUrl) : undefined,
104
+ }); };
105
+ exports.config = config;
106
+ exports.default = ReactEditor;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/index.js CHANGED
@@ -3,103 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const react_1 = require("react");
7
- const jodit_react_1 = __importDefault(require("jodit-react"));
8
- const react_2 = __importDefault(require("react"));
9
- const ReactEditor = ({ onChange, onBlur, value, useUploadImage, apiUrl, imageUrl }) => {
10
- const editor = (0, react_1.useRef)(null);
11
- const uploaderConfig = {
12
- imagesExtensions: ['jpg', 'png', 'jpeg', 'gif', 'webp'],
13
- filesVariableName: function (t) {
14
- return 'files[' + t + ']';
15
- },
16
- url: apiUrl,
17
- withCredentials: false,
18
- format: 'json',
19
- method: 'POST',
20
- prepareData: function (formdata) {
21
- return formdata;
22
- },
23
- isSuccess: function (e) {
24
- const fn = this.jodit;
25
- if (e.data.files && e.data.files.length) {
26
- const tagName = 'img';
27
- e.data.files.forEach((filename, index) => {
28
- const elm = fn.createInside.element(tagName);
29
- elm.setAttribute('src', `${imageUrl}/${filename}`);
30
- fn.s.insertImage(elm, null, fn.o.imageDefaultWidth);
31
- });
32
- }
33
- return e.success;
34
- },
35
- getMessage: function (e) {
36
- return e.data.messages && Array.isArray(e.data.messages)
37
- ? e.data.messages.join('')
38
- : '';
39
- },
40
- process: function (resp) {
41
- let files = [];
42
- files.unshift(resp.data);
43
- return {
44
- files: resp.data,
45
- error: resp.msg,
46
- msg: resp.msg,
47
- };
48
- },
49
- error: function (e) {
50
- this.j.e.fire('errorMessage', e.message, 'error', 4000);
51
- },
52
- defaultHandlerError: function (e) {
53
- this.j.e.fire('errorMessage', e.message);
54
- },
55
- };
56
- const config = (0, react_1.useMemo)(() => ({
57
- readonly: false,
58
- placeholder: 'Start typing...',
59
- toolbarAdaptive: false,
60
- useSearch: false,
61
- language: "en",
62
- allowResizeX: false,
63
- allowResizeY: false,
64
- height: 400,
65
- enableDragAndDropFileToEditor: true,
66
- showCharsCounter: true,
67
- showWordsCounter: true,
68
- showXPathInStatusbar: false,
69
- buttons: [
70
- 'source',
71
- '|',
72
- 'bold',
73
- 'italic',
74
- 'underline',
75
- '|',
76
- 'ul',
77
- 'ol',
78
- '|',
79
- `${useUploadImage ? 'image' : ''}`,
80
- 'file',
81
- '|',
82
- 'video',
83
- '|',
84
- 'link',
85
- '|',
86
- 'undo',
87
- 'redo',
88
- '|',
89
- 'hr',
90
- '|',
91
- 'eraser',
92
- '|',
93
- 'font',
94
- 'fontsize',
95
- 'paragraph',
96
- 'brush',
97
- '|',
98
- 'table',
99
- 'fullsize',
100
- ],
101
- uploader: useUploadImage ? uploaderConfig : undefined,
102
- }), []);
103
- return (react_2.default.createElement(jodit_react_1.default, { ref: editor, value: value, config: config, onBlur: onBlur, onChange: onChange }));
104
- };
105
- exports.default = ReactEditor;
6
+ exports.uploaderConfig = exports.config = exports.default = void 0;
7
+ var Editor_1 = require("./Editor");
8
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(Editor_1).default; } });
9
+ var Editor_2 = require("./Editor");
10
+ Object.defineProperty(exports, "config", { enumerable: true, get: function () { return Editor_2.config; } });
11
+ var Editor_3 = require("./Editor");
12
+ Object.defineProperty(exports, "uploaderConfig", { enumerable: true, get: function () { return Editor_3.uploaderConfig; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mbs-dev/react-editor",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "react editor",
5
5
  "main": "dist/index.js",
6
6
  "types": "types/index.d.ts",
@@ -23,10 +23,12 @@
23
23
  "homepage": "https://github.com/MOHAMMED-BE/react-editor#readme",
24
24
  "devDependencies": {
25
25
  "@types/react": "^18.2.60",
26
+ "tsc-hooks": "^1.1.2",
26
27
  "typescript": "^5.3.3"
27
28
  },
28
29
  "dependencies": {
29
30
  "jodit-react": "^1.3.39",
30
- "react": "^18.2.0"
31
+ "react": "^18.2.0",
32
+ "tslib": "^2.6.2"
31
33
  }
32
34
  }
package/src/Editor.tsx ADDED
@@ -0,0 +1,120 @@
1
+ import React from 'react';
2
+ import JoditEditor from "jodit-react";
3
+ import { EditorProps } from './Editor.types';
4
+
5
+ const ReactEditor: React.FC<EditorProps> = ({ onChange, onBlur, value, config }) => {
6
+ // const editor = useRef(null);
7
+
8
+ return (
9
+ <JoditEditor
10
+ // ref={ref}
11
+ value={value}
12
+ config={config}
13
+ onBlur={onBlur}
14
+ onChange={onChange}
15
+ />
16
+ );
17
+ };
18
+
19
+
20
+ export const uploaderConfig = (apiUrl: string | undefined, imageUrl: string | undefined) => ({
21
+ imagesExtensions: ['jpg', 'png', 'jpeg', 'gif', 'webp'],
22
+ filesVariableName: function (t: number): string {
23
+ return 'files[' + t + ']';
24
+ },
25
+ url: apiUrl,
26
+ withCredentials: false,
27
+ format: 'json',
28
+ method: 'POST',
29
+ prepareData: function (formdata: FormData): FormData {
30
+ return formdata;
31
+ },
32
+ isSuccess: function (this: any, e: any): boolean {
33
+ const fn = this.jodit
34
+
35
+ if (e.data.files && e.data.files.length) {
36
+ const tagName = 'img';
37
+ e.data.files.forEach((filename: string, index: number) => {
38
+ const elm = fn.createInside.element(tagName);
39
+ elm.setAttribute('src', `${imageUrl}/${filename}`);
40
+ fn.s.insertImage(elm as HTMLImageElement, null, fn.o.imageDefaultWidth);
41
+ });
42
+ }
43
+
44
+ return e.success;
45
+ },
46
+ getMessage: function (e: any): string {
47
+ return e.data.messages && Array.isArray(e.data.messages)
48
+ ? e.data.messages.join('')
49
+ : '';
50
+ },
51
+ process: function (resp: any): { files: any[]; error: string; msg: string } {
52
+ let files: any[] = [];
53
+ files.unshift(resp.data);
54
+ return {
55
+ files: resp.data,
56
+ error: resp.msg,
57
+ msg: resp.msg,
58
+ };
59
+ },
60
+
61
+ error: function (this: any, e: Error): void {
62
+ this.j.e.fire('errorMessage', e.message, 'error', 4000);
63
+ },
64
+
65
+ defaultHandlerError: function (this: any, e: any): void {
66
+ this.j.e.fire('errorMessage', e.message);
67
+ },
68
+ });
69
+
70
+
71
+ export const config = (includeUploader?: boolean | undefined, apiUrl?: string | undefined, imageUrl?: string | undefined) => ({
72
+ readonly: false,
73
+ placeholder: 'Start typing...',
74
+ toolbarAdaptive: false,
75
+ useSearch: false,
76
+ language: "en",
77
+ allowResizeX: false,
78
+ allowResizeY: false,
79
+ height: 400,
80
+ enableDragAndDropFileToEditor: true,
81
+ showCharsCounter: true,
82
+ showWordsCounter: true,
83
+ showXPathInStatusbar: false,
84
+
85
+ buttons: [
86
+ 'source',
87
+ '|',
88
+ 'bold',
89
+ 'italic',
90
+ 'underline',
91
+ '|',
92
+ 'ul',
93
+ 'ol',
94
+ '|',
95
+ 'image',
96
+ // 'file',
97
+ '|',
98
+ 'video',
99
+ '|',
100
+ 'link',
101
+ '|',
102
+ 'undo',
103
+ 'redo',
104
+ '|',
105
+ 'hr',
106
+ '|',
107
+ 'eraser',
108
+ '|',
109
+ 'font',
110
+ 'fontsize',
111
+ 'paragraph',
112
+ 'brush',
113
+ '|',
114
+ 'table',
115
+ 'fullsize',
116
+ ],
117
+ uploader: includeUploader ? uploaderConfig(apiUrl, imageUrl) : undefined,
118
+ })
119
+
120
+ export default ReactEditor
@@ -0,0 +1,10 @@
1
+ export interface EditorProps {
2
+ onChange?: any;
3
+ onBlur?: any;
4
+ value?: any;
5
+ useUploadImage?: boolean;
6
+ apiUrl?: string;
7
+ imageUrl?: string;
8
+ config?: any
9
+ // ref?: any;
10
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { default } from './Editor'
2
+ export { config } from './Editor'
3
+ export { uploaderConfig } from './Editor'
package/tsconfig.json CHANGED
@@ -1,17 +1,34 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "jsx": "react",
4
- "skipLibCheck": true,
5
- "target": "ES2019",
6
- "module": "CommonJS",
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "strict": true,
10
- "esModuleInterop": true
4
+ "esModuleInterop": true,
5
+ "skipLibCheck": true,
6
+ "declaration": true,
7
+ "declarationDir": "types",
8
+ "outDir": "./dist",
9
+ // "rootDir": "./src",
10
+ "target": "es5",
11
+ "moduleResolution": "node",
12
+ "removeComments": true,
13
+ "strict": true,
14
+ "alwaysStrict": true,
15
+ "downlevelIteration": true,
16
+ "strictNullChecks": true,
17
+ "strictFunctionTypes": true,
18
+ "strictBindCallApply": true,
19
+ "strictPropertyInitialization": true,
20
+ "experimentalDecorators": true,
21
+ "allowJs": true,
22
+ "noImplicitAny": true,
23
+ "noImplicitReturns": true,
24
+ "noUnusedLocals": true,
25
+ "noImplicitOverride": true,
26
+ "noImplicitThis": true,
27
+ "resolveJsonModule": true,
28
+ "lib": ["es5", "esnext", "dom", "scripthost", "es2015.iterable"],
11
29
  },
12
30
  "include": [
13
- "src",
14
- "types/**/*.d.ts"
31
+ "src"
15
32
  ],
16
33
  "exclude": [
17
34
  "node_modules"
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { EditorProps } from './Editor.types';
3
+ declare const ReactEditor: React.FC<EditorProps>;
4
+ export declare const uploaderConfig: (apiUrl: string | undefined, imageUrl: string | undefined) => {
5
+ imagesExtensions: string[];
6
+ filesVariableName: (t: number) => string;
7
+ url: string | undefined;
8
+ withCredentials: boolean;
9
+ format: string;
10
+ method: string;
11
+ prepareData: (formdata: FormData) => FormData;
12
+ isSuccess: (this: any, e: any) => boolean;
13
+ getMessage: (e: any) => string;
14
+ process: (resp: any) => {
15
+ files: any[];
16
+ error: string;
17
+ msg: string;
18
+ };
19
+ error: (this: any, e: Error) => void;
20
+ defaultHandlerError: (this: any, e: any) => void;
21
+ };
22
+ export declare const config: (includeUploader?: boolean | undefined, apiUrl?: string | undefined, imageUrl?: string | undefined) => {
23
+ readonly: boolean;
24
+ placeholder: string;
25
+ toolbarAdaptive: boolean;
26
+ useSearch: boolean;
27
+ language: string;
28
+ allowResizeX: boolean;
29
+ allowResizeY: boolean;
30
+ height: number;
31
+ enableDragAndDropFileToEditor: boolean;
32
+ showCharsCounter: boolean;
33
+ showWordsCounter: boolean;
34
+ showXPathInStatusbar: boolean;
35
+ buttons: string[];
36
+ uploader: {
37
+ imagesExtensions: string[];
38
+ filesVariableName: (t: number) => string;
39
+ url: string | undefined;
40
+ withCredentials: boolean;
41
+ format: string;
42
+ method: string;
43
+ prepareData: (formdata: FormData) => FormData;
44
+ isSuccess: (this: any, e: any) => boolean;
45
+ getMessage: (e: any) => string;
46
+ process: (resp: any) => {
47
+ files: any[];
48
+ error: string;
49
+ msg: string;
50
+ };
51
+ error: (this: any, e: Error) => void;
52
+ defaultHandlerError: (this: any, e: any) => void;
53
+ } | undefined;
54
+ };
55
+ export default ReactEditor;
@@ -0,0 +1,9 @@
1
+ export interface EditorProps {
2
+ onChange?: any;
3
+ onBlur?: any;
4
+ value?: any;
5
+ useUploadImage?: boolean;
6
+ apiUrl?: string;
7
+ imageUrl?: string;
8
+ config?: any;
9
+ }
package/types/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- declare module '@mbs-dev/react-editor';
1
+ export { default } from './Editor';
2
+ export { config } from './Editor';
3
+ export { uploaderConfig } from './Editor';
package/src/index.tsx DELETED
@@ -1,132 +0,0 @@
1
- import { FC, useMemo, useRef } from 'react';
2
- import JoditEditor from "jodit-react";
3
- import React from 'react';
4
-
5
- interface EditorProps {
6
- onChange?: any;
7
- onBlur?: any;
8
- value?: any;
9
- useUploadImage?: boolean;
10
- apiUrl?: string;
11
- imageUrl?: string;
12
- }
13
-
14
- const ReactEditor: FC<EditorProps> = ({ onChange, onBlur, value, useUploadImage, apiUrl, imageUrl }) => {
15
- const editor = useRef(null);
16
-
17
- const uploaderConfig = {
18
- imagesExtensions: ['jpg', 'png', 'jpeg', 'gif', 'webp'],
19
- filesVariableName: function (t: number): string {
20
- return 'files[' + t + ']';
21
- },
22
- url: apiUrl,
23
- withCredentials: false,
24
- format: 'json',
25
- method: 'POST',
26
- prepareData: function (formdata: FormData): FormData {
27
- return formdata;
28
- },
29
- isSuccess: function (this: any, e: any): boolean {
30
- const fn = this.jodit
31
-
32
- if (e.data.files && e.data.files.length) {
33
- const tagName = 'img';
34
- e.data.files.forEach((filename: string, index: number) => {
35
- const elm = fn.createInside.element(tagName);
36
- elm.setAttribute('src', `${imageUrl}/${filename}`);
37
- fn.s.insertImage(elm as HTMLImageElement, null, fn.o.imageDefaultWidth);
38
- });
39
- }
40
-
41
- return e.success;
42
- },
43
- getMessage: function (e: any): string {
44
- return e.data.messages && Array.isArray(e.data.messages)
45
- ? e.data.messages.join('')
46
- : '';
47
- },
48
- process: function (resp: any): { files: any[]; error: string; msg: string } {
49
- let files: any[] = [];
50
- files.unshift(resp.data);
51
- return {
52
- files: resp.data,
53
- error: resp.msg,
54
- msg: resp.msg,
55
- };
56
- },
57
-
58
- error: function (this: any, e: Error): void {
59
- this.j.e.fire('errorMessage', e.message, 'error', 4000);
60
- },
61
-
62
- defaultHandlerError: function (this: any, e: any): void {
63
- this.j.e.fire('errorMessage', e.message);
64
- },
65
- };
66
-
67
-
68
- const config = useMemo(
69
- () => ({
70
- readonly: false,
71
- placeholder: 'Start typing...',
72
- toolbarAdaptive: false,
73
- useSearch: false,
74
- language: "en",
75
- allowResizeX: false,
76
- allowResizeY: false,
77
- height: 400,
78
- enableDragAndDropFileToEditor: true,
79
- showCharsCounter: true,
80
- showWordsCounter: true,
81
- showXPathInStatusbar: false,
82
-
83
- buttons: [
84
- 'source',
85
- '|',
86
- 'bold',
87
- 'italic',
88
- 'underline',
89
- '|',
90
- 'ul',
91
- 'ol',
92
- '|',
93
- `${useUploadImage ? 'image' : ''}`,
94
- 'file',
95
- '|',
96
- 'video',
97
- '|',
98
- 'link',
99
- '|',
100
- 'undo',
101
- 'redo',
102
- '|',
103
- 'hr',
104
- '|',
105
- 'eraser',
106
- '|',
107
- 'font',
108
- 'fontsize',
109
- 'paragraph',
110
- 'brush',
111
- '|',
112
- 'table',
113
- 'fullsize',
114
- ],
115
- uploader: useUploadImage ? uploaderConfig : undefined,
116
- }),
117
- []
118
- );
119
-
120
-
121
- return (
122
- <JoditEditor
123
- ref={editor}
124
- value={value}
125
- config={config}
126
- onBlur={onBlur}
127
- onChange={onChange}
128
- />
129
- );
130
- };
131
-
132
- export default ReactEditor