inital commit

This commit is contained in:
2026-01-01 15:25:19 +05:30
commit f0ae49465a
36361 changed files with 4894111 additions and 0 deletions

1
node_modules/jodit-react/.nvmrc generated vendored Normal file
View File

@@ -0,0 +1 @@
20

98
node_modules/jodit-react/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,98 @@
# Changelog
> **Tags:**
>
> - :boom: [Breaking Change]
> - :rocket: [New Feature]
> - :bug: [Bug Fix]
> - :memo: [Documentation]
> - :house: [Internal]
> - :nail_care: [Polish]
## 5.0.9
- Fixed ref forwarding issue
## 5.0.7
- [Fix: Avoid "Abort async" error by utilizing waitForReady API in Jodit destruct handling #287](https://github.com/jodit/jodit-react/pull/287)
- Fixed Config type issue
- Support React 19
## 4.0.1
-
## 1.3.19
#### :rocket: New Feature
- The package now re-exports imperative Jodit, so you can write plugins and use all Jodit helpers
```js
import JoditEditor, { Jodit } from '../../src/';
/**
* @param {Jodit} jodit
*/
function preparePaste(jodit) {
jodit.e.on(
'paste',
e => {
if (confirm('Change pasted content?')) {
jodit.e.stopPropagation('paste');
jodit.s.insertHTML(
Jodit.modules.Helpers.getDataTransfer(e)
.getData(Jodit.constants.TEXT_HTML)
.replace(/a/g, 'b')
);
return false;
}
},
{ top: true }
);
}
Jodit.plugins.add('preparePaste', preparePaste);
//...
return <JoditEditor />;
```
#### :house: Internal
- Update
```
eslint-plugin-react-hooks ^4.5.0 → ^4.6.0
@babel/core ^7.16.0 → ^7.19.0
@babel/eslint-parser ^7.17.0 → ^7.18.9
@babel/preset-env ^7.16.0 → ^7.19.0
@babel/preset-react ^7.16.0 → ^7.18.6
@types/react ^16.14.2 → ^18.0.18
babel-loader ^8.2.2 → ^8.2.5
css-loader ^3.6.0 → ^6.7.1
eslint ^8.9.0 → ^8.23.0
eslint-config-prettier ^8.4.0 → ^8.5.0
eslint-plugin-prettier ^4.0.0 → ^4.2.1
eslint-plugin-react ^7.28.0 → ^7.31.8
husky ^7.0.4 → ^8.0.1
lint-staged ^12.3.4 → ^13.0.3
prettier ^2.5.1 → ^2.7.1
style-loader ^0.20.3 → ^3.3.1
webpack ^4.44.2 → ^5.74.0
webpack-cli ^3.3.12 → ^4.10.0
webpack-dev-server ^3.11.0 → ^4.11.0
```
## 1.3.18
#### :bug: Bug Fix
- [Jodit not cleaning up after unmount #196](https://github.com/jodit/jodit-react/issues/196)
## 1.2.1
#### :bug: Bug Fix
- [Editor duplicates after re-render (state change) #172](https://github.com/jodit/jodit-react/issues/172)

21
node_modules/jodit-react/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 It can be easy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

123
node_modules/jodit-react/README.md generated vendored Normal file
View File

@@ -0,0 +1,123 @@
# React Jodit WYSIWYG Editor
[![npm](https://img.shields.io/npm/v/jodit-react.svg)](https://www.npmjs.com/package/jodit-react)
[![npm](https://img.shields.io/npm/dm/jodit-react.svg)](https://www.npmjs.com/package/jodit-react)
[![npm](https://img.shields.io/npm/l/jodit-react.svg)](https://www.npmjs.com/package/jodit-react)
React wrapper for [Jodit](https://xdsoft.net/jodit/)
> [Jodit React PRO](https://xdsoft.net/jodit/pro/) it is an extended version of Jodit React with the same API, but with a lot more features.
## Installation
```bash
npm install jodit-react --save
```
## Update editor version
```bash
npm update jodit-react
```
## Run demo
```bash
npm install --dev
npm run demo
```
and open
```
http://localhost:4000/
```
## Usage
### 1. Require and use Jodit-react component inside your application.
```jsx
import React, { useState, useRef, useMemo } from 'react';
import JoditEditor from 'jodit-react';
const Example = ({ placeholder }) => {
const editor = useRef(null);
const [content, setContent] = useState('');
const config = useMemo(() => ({
readonly: false, // all options from https://xdsoft.net/jodit/docs/,
placeholder: placeholder || 'Start typings...'
}),
[placeholder]
);
return (
<JoditEditor
ref={editor}
value={content}
config={config}
tabIndex={1} // tabIndex of textarea
onBlur={newContent => setContent(newContent)} // preferred to use only this option to update the content for performance reasons
onChange={newContent => {}}
/>
);
};
```
### Jodit plugins
You can use all Jodit features and write your [own plugin](https://xdsoft.net/jodit/docs/modules/plugin.html) for example.
```js
import JoditEditor, { Jodit } from 'jodit-react';
/**
* @param {Jodit} jodit
*/
function preparePaste(jodit) {
jodit.e.on(
'paste',
e => {
if (confirm('Change pasted content?')) {
jodit.e.stopPropagation('paste');
jodit.s.insertHTML(
Jodit.modules.Helpers.getDataTransfer(e)
.getData(Jodit.constants.TEXT_HTML)
.replace(/a/g, 'b')
);
return false;
}
},
{ top: true }
);
}
Jodit.plugins.add('preparePaste', preparePaste);
//...
return <JoditEditor />;
```
You can see how to write plugins [in the documentation](https://xdsoft.net/jodit/pro/docs/how-to/create-plugin.md) or [on the stand](https://xdsoft.net/jodit/pro/docs/getting-started/examples.md#jodit-example-paste-link)
## Use with Jodit PRO
You can connect any Jodit constructor and set it as the `JoditConstructor` property of the component.
```jsx
import React from 'react';
import JoditEditor from 'jodit-react';
import {Jodit} from 'jodit-pro';
import 'jodit-pro/es5/jodit.min.css';
// ...
function App() {
return <JoditEditor JoditConstructor={Jodit} />;
}
```
## License
This package is available under `MIT` License.

10
node_modules/jodit-react/SECURITY.md generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# Reporting security issues
If you believe you have found a security issue in the Jodit software, please contact us immediately.
When reporting a suspected security problem, please bear this in mind:
* Make sure to provide as many details as possible about the vulnerability.
* Please do not disclose publicly any security issues until we fix them and publish security releases.
Contact the security team at security@xdsoft.net. As soon as we receive the security report, we'll work promptly to confirm the issue and then to provide a security fix.

2
node_modules/jodit-react/build/jodit-react.js generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/

20
node_modules/jodit-react/build/types/JoditEditor.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import React from 'react';
import type { IJodit } from 'jodit/esm/types/jodit';
import type { Jodit as JoditBaseConstructor } from 'jodit/esm/index';
import type { Config } from 'jodit/esm/config';
import { Jodit } from './include.jodit';
import type { DeepPartial } from 'jodit/esm/types';
interface Props<T extends typeof JoditBaseConstructor = typeof Jodit> {
JoditConstructor?: T;
config?: DeepPartial<Config>;
className?: string;
id?: string;
name?: string;
onBlur?: (value: string, event: MouseEvent) => void;
onChange?: (value: string) => void;
tabIndex?: number;
value?: string;
editorRef?: (editor: IJodit) => void;
}
declare const JoditEditor: React.ForwardRefExoticComponent<Props<typeof JoditBaseConstructor> & React.RefAttributes<IJodit>>;
export default JoditEditor;

101
node_modules/jodit-react/build/types/JoditEditor.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
import React, { useEffect, useRef, forwardRef } from 'react';
import { Jodit } from './include.jodit';
function usePrevious(value) {
const ref = useRef('');
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
const JoditEditor = forwardRef(({ JoditConstructor = Jodit, className, config, id, name, onBlur, onChange, tabIndex, value, editorRef }, ref) => {
const textAreaRef = useRef(null);
const joditRef = useRef(null);
useEffect(() => {
const element = textAreaRef.current;
const jodit = JoditConstructor.make(element, config);
joditRef.current = jodit;
if (typeof editorRef === 'function') {
editorRef(jodit);
}
return () => {
if (jodit.isReady) {
jodit.destruct();
}
else {
jodit
.waitForReady()
.then(joditInstance => joditInstance.destruct());
}
};
}, [JoditConstructor, config, editorRef]);
useEffect(() => {
if (ref) {
if (typeof ref === 'function') {
ref(joditRef.current);
}
else {
ref.current = joditRef.current;
}
}
}, [textAreaRef, ref, joditRef]);
const preClassName = usePrevious(className ?? '');
useEffect(() => {
const classList = joditRef.current?.container?.classList;
if (preClassName !== className &&
typeof preClassName === 'string') {
preClassName
.split(/\s+/)
.filter(Boolean)
.forEach(cl => classList?.remove(cl));
}
if (className && typeof className === 'string') {
className
.split(/\s+/)
.filter(Boolean)
.forEach(cl => classList?.add(cl));
}
}, [className, preClassName]);
useEffect(() => {
if (joditRef.current?.workplace) {
joditRef.current.workplace.tabIndex = tabIndex || -1;
}
}, [tabIndex]);
useEffect(() => {
const jodit = joditRef.current;
if (!jodit?.events || !(onBlur || onChange)) {
return;
}
const onBlurHandler = (event) => onBlur && onBlur(joditRef?.current?.value ?? '', event);
const onChangeHandler = (value) => onChange && onChange(value);
// adding event handlers
jodit.events
.on('blur', onBlurHandler)
.on('change', onChangeHandler);
return () => {
// Remove event handlers
jodit.events
?.off('blur', onBlurHandler)
.off('change', onChangeHandler);
};
}, [onBlur, onChange]);
useEffect(() => {
const jodit = joditRef.current;
const updateValue = () => {
if (jodit && value !== undefined && jodit.value !== value) {
jodit.value = value;
}
};
if (jodit) {
if (jodit.isReady) {
updateValue();
}
else {
jodit.waitForReady().then(updateValue);
}
}
}, [value]);
return (React.createElement("div", { className: 'jodit-react-container' },
React.createElement("textarea", { defaultValue: value, name: name, id: id, ref: textAreaRef })));
});
JoditEditor.displayName = 'JoditEditor';
export default JoditEditor;

View File

@@ -0,0 +1,4 @@
import type { Jodit as JoditConstructorType } from 'jodit/esm/jodit';
import 'jodit/esm/plugins/all';
export declare const Jodit: typeof JoditConstructorType;

View File

@@ -0,0 +1,4 @@
import { Jodit as JoditES5 } from 'jodit/esm/index';
import 'jodit/es2021/jodit.min.css';
import 'jodit/esm/plugins/all';
export const Jodit = JoditES5;

4
node_modules/jodit-react/build/types/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import JoditEditor from './JoditEditor';
import { Jodit } from './include.jodit';
export default JoditEditor;
export { Jodit };

4
node_modules/jodit-react/build/types/index.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import JoditEditor from './JoditEditor';
import { Jodit } from './include.jodit';
export default JoditEditor;
export { Jodit };

185
node_modules/jodit-react/examples/app.css generated vendored Normal file
View File

@@ -0,0 +1,185 @@
html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
html, body {
height: 100%;
margin: 0;
}
body {
font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 16px;
-webkit-font-smoothing: antialiased;
text-rendering: optimizelegibility;
line-height: 1.5;
font-weight: 300;
}
body {
display: flex;
flex-direction: column;
}
header,
#main_container {
flex: 1 0 auto;
}
.jodit_wysiwyg {
color: #000;
padding: 10px;
overflow-x: auto;
min-height: 40px;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.table, .p {
margin: 0 0 16px 0;
}
.table {
border: 0;
border-collapse: collapse;
empty-cells: show;
max-width: 100%;
border-spacing: 0;
*border-collapse: collapse;
}
. table tr {
user-select: none;
-o-user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
. table td, . table th {
user-select: text;
-o-user-select: text;
-moz-user-select: text;
-khtml-user-select: text;
-webkit-user-select: text;
-ms-user-select: text;
}
. table th, . table td {
box-sizing: border-box;
padding: 2px 5px;
vertical-align: top;
}
.table td, . table th {
border: 1px solid #ddd;
}
.container {
width: 1000px;
margin: 0 auto;
}
nav {
height: 30px;
background: linear-gradient(to left, #28a5f5, #1e87f0);
padding: 0;
overflow: hidden;
}
footer nav {
background: #f9f9f9;
margin-top: 20px;
}
nav > ul {
padding: 0;
margin: 0;
}
nav > ul > li {
list-style: none;
display: inline-block;
padding: 0;
margin: 0;
}
nav > ul > li + li {
margin-left: 23px;
}
nav ul li a {
color: #ddd;
text-decoration: none;
text-transform: uppercase;
font-size: 0.625rem;
line-height: 30px;
}
nav ul li a:hover {
color: #aaa;
text-decoration: underline;
}
footer nav ul li a {
color: #3f3f3f;
}
nav ul li ul {
position: absolute;
margin: 0;
padding: 0;
background-color: #208bf1;
display: none;
}
nav > ul > li:hover > ul {
display: block;
}
nav ul li ul li {
list-style: none;
display: block;
padding: 0;
margin: 0;
}
nav ul li ul li a {
padding: 5px;
}
.layout {
display: flex;
flex-direction: row;
}
.layout > * {
}
.leftside {
width: 20%;
padding: 10px 10px 10px 0;
}
.rightside {
width: 80%;
padding: 10px 0 10px 10px;
}
pre {
white-space: pre-wrap;
background-color: #3f3f3f;
color: #fff;
padding: 10px;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 500;
}

17
node_modules/jodit-react/examples/app.tsx generated vendored Normal file
View File

@@ -0,0 +1,17 @@
import './app.css';
import React, { StrictMode } from 'react';
import Form from './components/Form';
// For React < 18
// import ReactDOM from 'react-dom';
// ReactDOM.render(<Form />, document.getElementById('editor'));
import { createRoot } from 'react-dom/client';
const container = document.getElementById('editor')!;
const root = createRoot(container);
root.render(
<StrictMode>
<Form />
</StrictMode>
);

View File

@@ -0,0 +1,5 @@
.simple-textarea {
display: block;
width: 100%;
min-height: 100px;
}

148
node_modules/jodit-react/examples/components/Form.tsx generated vendored Normal file
View File

@@ -0,0 +1,148 @@
import React, { type ChangeEvent, useCallback, useState } from 'react';
import JoditEditor, { Jodit } from '../../src/';
import './Form.css';
import type { IJodit } from 'jodit/types/types/jodit';
/**
* @param {Jodit} jodit
*/
function preparePaste(jodit: IJodit) {
jodit.e.on(
'paste',
e => {
if (confirm('Change pasted content?')) {
jodit.e.stopPropagation('paste');
jodit.s.insertHTML(
Jodit.modules.Helpers.getDataTransfer(e)!
.getData(Jodit.constants.TEXT_HTML)
?.replace(/a/g, 'b') ?? ''
);
return false;
}
},
{ top: true }
);
}
Jodit.plugins.add('preparePaste', preparePaste);
const Form = () => {
const [isSource, setSource] = useState(false);
const [config, setConfig] = useState({
toolbarAdaptive: false,
readonly: false,
toolbar: true
});
const [textAreaValue, setTextAreaValue] = useState('Test');
const [inputValue, setInputValue] = useState('');
const [spin, setSpin] = useState(1);
const toggleToolbar = useCallback(
() =>
setConfig(config => ({
...config,
toolbar: !config.toolbar
})),
[]
);
const toggleReadOnly = useCallback(
() =>
setConfig(config => ({
...config,
readonly: !config.readonly
})),
[]
);
const handleBlurAreaChange = useCallback(
(textAreaValue: string, event: MouseEvent) => {
console.log('handleBlurAreaChange', textAreaValue, event);
},
[]
);
const handleWYSIWYGChange = useCallback((newTextAreaValue: string) => {
console.log('handleWYSIWYGChange', newTextAreaValue);
setTextAreaValue(newTextAreaValue);
setInputValue(newTextAreaValue);
return setTextAreaValue(() => newTextAreaValue);
}, []);
const handleNativeTextAreaChange = useCallback((e: ChangeEvent) => {
const value = (e.target as HTMLTextAreaElement).value;
console.log('handleNativeTextAreaChange', value);
setTextAreaValue(value);
setInputValue(value);
}, []);
const handleInputChange = useCallback(
(e: ChangeEvent) => {
const { value } = e.target as HTMLInputElement;
setInputValue(value);
handleWYSIWYGChange(value);
},
[handleWYSIWYGChange]
);
const handleSpin = useCallback(() => setSpin(spin => ++spin), []);
const onSourceChange = useCallback((e: ChangeEvent) => {
setSource((e.target as HTMLInputElement).checked);
}, []);
return (
<div>
<label>
<input
type="checkbox"
onChange={onSourceChange}
checked={isSource}
/>{' '}
Source
</label>
{!isSource ? (
<JoditEditor
config={config}
onChange={handleWYSIWYGChange}
onBlur={handleBlurAreaChange}
value={textAreaValue}
/>
) : (
<textarea
className={'simple-textarea'}
onChange={handleNativeTextAreaChange}
value={textAreaValue}
/>
)}
<input
onChange={handleInputChange}
placeholder={'enter some text'}
type={'text'}
value={inputValue}
/>
<button onClick={toggleReadOnly} type={'button'}>
{'Toggle Read-Only'}
</button>
<button onClick={toggleToolbar} type={'button'}>
{'Toggle Toolbar'}
</button>
<button type={'button'} onClick={handleSpin}>
{`Spin ${spin}`}
</button>
</div>
);
};
export default Form;

66
node_modules/jodit-react/examples/index.html generated vendored Normal file
View File

@@ -0,0 +1,66 @@
<!doctype html>
<!--
* Jodit Editor (https://xdsoft.net/jodit/)
* License https://xdsoft.net/jodit/license.html
* Copyright 2013-2018 Valeriy Chupurnov https://xdsoft.net
-->
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Jodit React Example</title>
</head>
<body>
<header>
<nav>
<ul class="container">
<li><a href="https://xdsoft.net/jodit/">Jodit homepage</a></li>
<li><a href="https://xdsoft.net/jodit/docs/">Documentation</a></li>
<li><a href="https://github.com/xdan/jodit/">Github</a></li>
<li><a href="https://github.com/xdan/jodit/releases">Changelog</a></li>
<li style="float:right"><a href="https://github.com/xdan/jodit/releases/latest">Download</a></li>
</ul>
</nav>
</header>
<div id="main_container" class="container">
<div id="introduction">
<h3>JavaScript</h3>
<pre>
import './app.css';
import React from 'react';
import { createRoot } from 'react-dom/client';
import JoditEditor from "../src/JoditEditor";
const container = document.getElementById('editor')!;
const root = createRoot(container);
root.render(
&lt;StrictMode&gt;
&lt;Form /&gt;
&lt;/StrictMode&gt;
);
</pre>
</div>
<div class="result">
<div id="editor"></div>
</div>
</div>
<footer>
<nav>
<ul class="container">
<li><a href="https://xdsoft.net/jodit/">Jodit homepage</a></li>
<li><a href="https://xdsoft.net/jodit/docs/">Documentation</a></li>
<li><a href="https://github.com/xdan/jodit/">Github</a></li>
<li><a href="https://github.com/xdan/jodit/releases">Changelog</a></li>
<li style="float:right"><a href="https://github.com/xdan/jodit/releases/latest">Download</a></li>
</ul>
</nav>
</footer>
</body>
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,400,400i,700,700i" rel="stylesheet">
<script src="build/app.js"></script>
</html>

4
node_modules/jodit-react/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import JoditEditor from './build/types/JoditEditor';
import { Jodit } from './build/types/include.jodit';
export default JoditEditor;
export { Jodit };

96
node_modules/jodit-react/package.json generated vendored Normal file
View File

@@ -0,0 +1,96 @@
{
"name": "jodit-react",
"version": "5.2.38",
"description": "Jodit is awesome and usefully wysiwyg editor with filebrowser",
"main": "build/jodit-react.js",
"author": "Chupurnov <chupurnov@gmail.com> (https://xdsoft.net/)",
"keywords": [
"react",
"jodit",
"html",
"text",
"editor",
"wysisyg",
"rich editor",
"rich text editor",
"rte"
],
"dependencies": {
"jodit": "^4.7.9"
},
"peerDependencies": {
"react": "~0.14 || ^15 || ^16 || ^17 || ^18 || ^19",
"react-dom": "~0.14 || ^15 || ^16 || ^17 || ^18 || ^19"
},
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@jest/globals": "^29.7.0",
"@swc-node/register": "^1.10.9",
"@swc/core": "^1.10.7",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"@testing-library/user-event": "^14.6.0",
"@types/jest": "^29.5.14",
"@types/react": "^19.0.7",
"@types/react-dom": "^19.0.3",
"@typescript-eslint/eslint-plugin": "^8.20.0",
"css-loader": "^7.1.2",
"eslint": "9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-jest": "^28.11.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.1.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"prettier": "^3.4.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"replace": "^1.2.2",
"style-loader": "^4.0.0",
"swc-loader": "^0.2.6",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"webpack": "^5.97.1",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.0"
},
"scripts": {
"newversion": "npm version patch --no-git-tag-version && npm run github",
"lint": "npm run lint:ts && npm run lint:eslint",
"lint:ts": "tsc --noEmit",
"lint:eslint": "eslint ./",
"demo": "NODE_ENV=development node -r @swc-node/register ./node_modules/.bin/webpack serve --config ./examples/webpack.config.ts --mode development",
"start": "npm run demo",
"build": "npm run build:react && npm run build:types",
"build:react": "NODE_ENV=production node -r @swc-node/register ./node_modules/.bin/webpack --mode production",
"build:types": "rm -rf ./build/types && tsc --project tsconfig.types.json && npm run remove-css",
"remove-css": "replace \"import '[^']+.css';\" '' ./build/**/*.ts",
"github": "npm run git && git push --tags origin HEAD:main",
"git": "git add --all && git commit -m \"New version $npm_package_version. Read more https://github.com/jodit/jodit-react/releases/tag/$npm_package_version \" && git tag $npm_package_version",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jodit/jodit-react.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/jodit/jodit-react/issues"
},
"homepage": "https://xdsoft.net/jodit/",
"ava": {
"extensions": [
"ts",
"tsx"
],
"require": [
"@swc-node/register"
],
"files": [
"packages/**/*.spec.{ts,tsx}"
]
}
}

165
node_modules/jodit-react/src/JoditEditor.tsx generated vendored Normal file
View File

@@ -0,0 +1,165 @@
import React, { useEffect, useRef, forwardRef } from 'react';
import type { IJodit } from 'jodit/esm/types/jodit';
import type { Jodit as JoditBaseConstructor } from 'jodit/esm/index';
import type { Config } from 'jodit/esm/config';
import { Jodit } from './include.jodit';
import type { DeepPartial } from 'jodit/esm/types';
function usePrevious(value: string): string {
const ref = useRef<string>('');
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
interface Props<T extends typeof JoditBaseConstructor = typeof Jodit> {
JoditConstructor?: T;
config?: DeepPartial<Config>;
className?: string;
id?: string;
name?: string;
onBlur?: (value: string, event: MouseEvent) => void;
onChange?: (value: string) => void;
tabIndex?: number;
value?: string;
editorRef?: (editor: IJodit) => void;
}
const JoditEditor = forwardRef<IJodit, Props>(
(
{
JoditConstructor = Jodit,
className,
config,
id,
name,
onBlur,
onChange,
tabIndex,
value,
editorRef
},
ref
) => {
const textAreaRef = useRef<HTMLTextAreaElement | null>(null);
const joditRef = useRef<IJodit | null>(null);
useEffect(() => {
const element = textAreaRef.current!;
const jodit = JoditConstructor.make(element, config);
joditRef.current = jodit;
if (typeof editorRef === 'function') {
editorRef(jodit);
}
return () => {
if (jodit.isReady) {
jodit.destruct();
} else {
jodit
.waitForReady()
.then(joditInstance => joditInstance.destruct());
}
};
}, [JoditConstructor, config, editorRef]);
useEffect(() => {
if (ref) {
if (typeof ref === 'function') {
ref(joditRef.current);
} else {
ref.current = joditRef.current;
}
}
}, [textAreaRef, ref, joditRef]);
const preClassName = usePrevious(className ?? '');
useEffect(() => {
const classList = joditRef.current?.container?.classList;
if (
preClassName !== className &&
typeof preClassName === 'string'
) {
preClassName
.split(/\s+/)
.filter(Boolean)
.forEach(cl => classList?.remove(cl));
}
if (className && typeof className === 'string') {
className
.split(/\s+/)
.filter(Boolean)
.forEach(cl => classList?.add(cl));
}
}, [className, preClassName]);
useEffect(() => {
if (joditRef.current?.workplace) {
joditRef.current.workplace.tabIndex = tabIndex || -1;
}
}, [tabIndex]);
useEffect(() => {
const jodit = joditRef.current;
if (!jodit?.events || !(onBlur || onChange)) {
return;
}
const onBlurHandler = (event: MouseEvent) =>
onBlur && onBlur(joditRef?.current?.value ?? '', event);
const onChangeHandler = (value: string) =>
onChange && onChange(value);
// adding event handlers
jodit.events
.on('blur', onBlurHandler)
.on('change', onChangeHandler);
return () => {
// Remove event handlers
jodit.events
?.off('blur', onBlurHandler)
.off('change', onChangeHandler);
};
}, [onBlur, onChange]);
useEffect(() => {
const jodit = joditRef.current;
const updateValue = () => {
if (jodit && value !== undefined && jodit.value !== value) {
jodit.value = value;
}
};
if (jodit) {
if (jodit.isReady) {
updateValue();
} else {
jodit.waitForReady().then(updateValue);
}
}
}, [value]);
return (
<div className={'jodit-react-container'}>
<textarea
defaultValue={value}
name={name}
id={id}
ref={textAreaRef}
/>
</div>
);
}
);
JoditEditor.displayName = 'JoditEditor';
export default JoditEditor;

7
node_modules/jodit-react/src/include.jodit.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import { Jodit as JoditES5 } from 'jodit/esm/index';
import type { Jodit as JoditConstructorType } from 'jodit/esm/jodit';
import 'jodit/es2021/jodit.min.css';
import 'jodit/esm/plugins/all';
export const Jodit: typeof JoditConstructorType = JoditES5;

5
node_modules/jodit-react/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import JoditEditor from './JoditEditor';
import { Jodit } from './include.jodit';
export default JoditEditor;
export { Jodit };

20
node_modules/jodit-react/tsconfig.json generated vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es2015",
"module": "ESNext",
"outDir": "./build",
"declaration": true,
"declarationDir": "./build/types",
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"moduleDetection": "force",
"allowJs": true,
"noUncheckedIndexedAccess": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"noImplicitAny": true
}
}