75 | ```
76 | #### Pass properties to the wrapping DOM element
77 |
78 | ```js
79 |
85 | ```
86 |
87 | **tag** attr is used to tell on which tag the editor is initialized.
88 |
89 | There are special tags: **a**, **button**, **img**, **input**. Do not use them in FroalaEditor component. To initialize the editor on a special tag, use `FroalaEditorA`, `FroalaEditorButton`, `FroalaEditorImg` and `FroalaEditorInput` components.
90 |
91 |
92 | ### Config
93 |
94 | You can pass editor options as component attribute (optional).
95 |
96 | `config={this.config}`
97 |
98 | You can pass any existing Froala option. Consult the [Froala documentation](https://www.froala.com/wysiwyg-editor/docs/options) to view the list of all the available options:
99 |
100 | ```js
101 | config={{
102 | placeholderText: 'Edit Your Content Here!',
103 | charCounterCount: false
104 | }}
105 | ```
106 |
107 | Aditional option is used:
108 | * **immediateReactModelUpdate**: (default: false) This option updates the React model as soon as a key is released in the editor. Note that it may affect performances.
109 |
110 | ### Events and Methods
111 |
112 | Events can be passed in with the options, with a key events and object where the key is the event name and the value is the callback function.
113 |
114 | ```js
115 | config={{
116 | placeholder: "Edit Me",
117 | events : {
118 | 'focus' : function(e, editor) {
119 | console.log(editor.selection.get());
120 | }
121 | }
122 | }}
123 | ```
124 |
125 | Using the editor instance from the arguments of the callback you can call editor methods as described in the [method docs](http://froala.com/wysiwyg-editor/docs/methods).
126 |
127 | Froala events are described in the [events docs](https://froala.com/wysiwyg-editor/docs/events).
128 |
129 |
130 | ### Model
131 |
132 | The WYSIWYG HTML editor content model.
133 |
134 | `model = {this.state.model}`
135 |
136 | Two way binding:
137 |
138 | ```jsx
139 | import React from 'react';
140 |
141 | class EditorComponent extends React.Component {
142 | constructor () {
143 | super();
144 |
145 | this.handleModelChange = this.handleModelChange.bind(this);
146 |
147 | this.state = {
148 | model: 'Example text'
149 | };
150 | }
151 |
152 | handleModelChange: function(model) {
153 | this.setState({
154 | model: model
155 | });
156 | }
157 |
158 | render () {
159 | return
163 | }
164 | }
165 | ```
166 |
167 | To achieve one way binding and pass only the initial editor content, simply do not pass `onModelChange` attribute.
168 |
169 | Use the content in other places:
170 |
171 | ```js
172 |
173 | ```
174 |
175 | ### Special tags
176 | You can also use the editor on **img**, **button**, **input** and **a** tags:
177 |
178 | ```js
179 |
182 |
185 |
188 |
191 | ```
192 |
193 | The model must be an object containing the attributes for your special tags. Example:
194 |
195 | ```js
196 | constructor () {
197 | super();
198 |
199 | this.handleModelChange = this.handleModelChange.bind(this);
200 |
201 | this.state = {
202 | model: {src: 'path/to/image.jpg'}
203 | };
204 | }
205 | ```
206 |
207 | * The model can contain a special attribute named **innerHTML** which inserts innerHTML in the element: If you are using 'button' tag, you can specify the button text like this:
208 |
209 | ```js
210 | this.state = {
211 | model: {innerHTML: 'Click Me'}
212 | };
213 | ```
214 | As the button text is modified by the editor, the **innerHTML** attribute from buttonModel model will be modified too.
215 |
216 | ## Manual Instantiation
217 |
218 | Gets the functionality to operate on the editor: create, destroy and get editor instance. Use it if you want to manually initialize the editor.
219 |
220 | `onManualControllerReady={this.handleManualController}`
221 |
222 | ```js
223 | handleManualController: function(initControls) {
224 | //...
225 | }
226 | ```
227 | The object received by the function will contain the following methods:
228 |
229 | - **initialize**: Call this method to initialize the Froala Editor
230 | - **destroy**: Call this method to destroy the Froala Editor
231 | - **getEditor**: Call this method to retrieve the editor that was created. This method will return *null* if the editor was not yet created
232 |
233 | ## Displaying HTML
234 |
235 | To display content created with the froala editor use the `FroalaEditorView` component.
236 |
237 | ```js
238 |
242 |
245 | ```
246 |
247 |
248 | ## Usage with Functional Component
249 |
250 | #### 1. Require and use Froala Editor component inside your application.
251 |
252 | ```jsx
253 | import React from 'react';
254 | import ReactDOM from 'react-dom/client';
255 |
256 | // Require Editor CSS files.
257 | import 'froala-editor/css/froala_style.min.css';
258 | import 'froala-editor/css/froala_editor.pkgd.min.css';
259 |
260 | import FroalaEditorComponent from 'react-froala-wysiwyg';
261 |
262 | // Import all Froala Editor plugins;
263 | // import 'froala-editor/js/plugins.pkgd.min.js';
264 |
265 | // Import a single Froala Editor plugin.
266 | // import 'froala-editor/js/plugins/align.min.js';
267 |
268 | // Import a language file.
269 | // import 'froala-editor/js/languages/de.js';
270 |
271 | // Import a third-party plugin.
272 | // import 'froala-editor/js/third_party/image_tui.min.js';
273 | // import 'froala-editor/js/third_party/embedly.min.js';
274 | // import 'froala-editor/js/third_party/spell_checker.min.js';
275 |
276 | // Include font-awesome css if required.
277 | // install using "npm install font-awesome --save"
278 | // import 'font-awesome/css/font-awesome.css';
279 | // import 'froala-editor/js/third_party/font_awesome.min.js';
280 |
281 | // Include special components if required.
282 | // import FroalaEditorView from 'react-froala-wysiwyg/FroalaEditorView';
283 | // import FroalaEditorA from 'react-froala-wysiwyg/FroalaEditorA';
284 | // import FroalaEditorButton from 'react-froala-wysiwyg/FroalaEditorButton';
285 | // import FroalaEditorImg from 'react-froala-wysiwyg/FroalaEditorImg';
286 | // import FroalaEditorInput from 'react-froala-wysiwyg/FroalaEditorInput';
287 |
288 | // Render Froala Editor component.
289 | const root = ReactDOM.createRoot(document.getElementById('editor'));
290 | root.render(
291 |
292 | )
293 |
294 | ```
295 | #### Add editor to UI by passing id to html element
296 |
297 | ```
298 |
299 |
300 | ```
301 |
302 | #### Pass properties to the wrapping DOM element
303 |
304 | ```js
305 |
311 | ```
312 | **tag** attr is used to tell on which tag the editor is initialized.
313 |
314 | There are special tags: **a**, **button**, **img**, **input**. Do not use them in FroalaEditor component. To initialize the editor on a special tag, use `FroalaEditorA`, `FroalaEditorButton`, `FroalaEditorImg` and `FroalaEditorInput` components.
315 |
316 |
317 | ### Config
318 |
319 | You can pass editor options as component attribute (optional).
320 |
321 | `config={config}`
322 |
323 | You can pass any existing Froala option. Consult the [Froala documentation](https://www.froala.com/wysiwyg-editor/docs/options) to view the list of all the available options:
324 |
325 | ```js
326 | config={{
327 | placeholderText: 'Edit Your Content Here!',
328 | charCounterCount: false
329 | }}
330 | ```
331 |
332 | Aditional option is used:
333 | * **immediateReactModelUpdate**: (default: false) This option updates the React model as soon as a key is released in the editor. Note that it may affect performances.
334 |
335 | ### Events and Methods
336 |
337 | Events can be passed in with the options, with a key events and object where the key is the event name and the value is the callback function.
338 |
339 | ```js
340 | config={{
341 | placeholder: "Edit Me",
342 | events : {
343 | 'focus' : function(e, editor) {
344 | console.log(editor.selection.get());
345 | }
346 | }
347 | }}
348 | ```
349 |
350 | Using the editor instance from the arguments of the callback you can call editor methods as described in the [method docs](http://froala.com/wysiwyg-editor/docs/methods).
351 |
352 | Froala events are described in the [events docs](https://froala.com/wysiwyg-editor/docs/events).
353 |
354 | Now you can use these buttons in options:
355 | ```javascript
356 | toolbarButtons: [['undo', 'redo' , 'bold'], ['alert', 'clear', 'insert']],
357 |
358 | ```
359 |
360 | ### Model
361 |
362 | The WYSIWYG HTML editor content model.
363 |
364 | `model = {model}`
365 |
366 | Two way binding:
367 |
368 | ```jsx
369 | import React,{ useState } from 'react';
370 |
371 | const App=()=> {
372 | const [model,setModel] = useState("Example Set");
373 |
374 | const handleModelChange= (event)=>{
375 | setModel(event)
376 | }
377 | return (
378 |
379 |
383 |
386 |
387 | );
388 | }
389 | ```
390 |
391 | To achieve one way binding and pass only the initial editor content, simply do not pass `onModelChange` attribute.
392 |
393 | Use the content in other places:
394 |
395 | ```js
396 |
397 | ```
398 |
399 | ### Special tags
400 | You can also use the editor on **img**, **button**, **input** and **a** tags:
401 |
402 | ```js
403 |
406 |
409 |
412 |
415 |
416 | ```
417 | The model must be an object containing the attributes for your special tags. Example:
418 |
419 | ```js
420 | model={{src: 'path/to/image.jpg',
421 | width:"300px",
422 | alt:"Old Clock"
423 | }}
424 | ```
425 |
426 | * The model can contain a special attribute named **innerHTML** which inserts innerHTML in the element: If you are using 'button' tag, you can specify the button text like this:
427 |
428 | ```js
429 | model={{innerHTML: 'Click Me'}}
430 | ```
431 | As the button text is modified by the editor, the **innerHTML** attribute from buttonModel model will be modified too.
432 |
433 | ## Usage with Server-Side Rendering
434 |
435 | When using Server-Side Rendering you can use Froala components as described previously. If you require additonal plugins or translations, you will have to use React lazy loading
436 | in order to load the plugins first. Please refer to the examples below.
437 |
438 | ### Class component
439 |
440 | ```js
441 | import React, { Suspense } from "react";
442 |
443 | import 'froala-editor/css/froala_editor.pkgd.min.css';
444 | import 'froala-editor/css/froala_style.css';
445 |
446 | const FroalaEditor = React.lazy(() => import('react-froala-wysiwyg'));
447 |
448 | export default class MyComponent extends React.Component {
449 | constructor () {
450 | super();
451 | this.state = {
452 | isInitialized: false
453 | };
454 | }
455 |
456 | componentDidMount() {
457 | // Import all Froala Editor plugins;
458 | import('froala-editor/js/plugins.pkgd.min.js').then(() => this.setState({isInitialized: true}));
459 | }
460 |
461 | render() {
462 | return <>
463 | {this.state.isInitialized && (
464 | Loading...}>
465 |
468 |
469 | )}
470 | >;
471 | }
472 | }
473 | ```
474 |
475 | ### Functional component
476 |
477 | ```js
478 | import React, { Suspense, useEffect, useState } from "react";
479 |
480 | import 'froala-editor/css/froala_editor.pkgd.min.css';
481 | import 'froala-editor/css/froala_style.css';
482 |
483 | const FroalaEditor = React.lazy(() => import('react-froala-wysiwyg'));
484 |
485 | export default function MyComponent() {
486 | const [isInitialized, setIsInitialized] = useState(false);
487 |
488 | useEffect(() => {
489 | async function initPlugins() {
490 | // Import all Froala Editor plugins;
491 | await import('froala-editor/js/plugins.pkgd.min.js');
492 | setIsInitialized(true);
493 | }
494 | if (!isInitialized) {
495 | initPlugins();
496 | }
497 | });
498 |
499 | return <>
500 | {isInitialized && (
501 | Loading...}>
502 |
505 |
506 | )}
507 | >;
508 | }
509 | ```
510 |
511 | ## Manual Instantiation
512 |
513 | Gets the functionality to operate on the editor: create, destroy and get editor instance. Use it if you want to manually initialize the editor.
514 |
515 | `onManualControllerReady={handleManualController}`
516 |
517 | ```js
518 | handleManualController =(initControls) =>{
519 | //...
520 | }
521 | ```
522 | The object received by the function will contain the following methods:
523 |
524 | - **initialize**: Call this method to initialize the Froala Editor
525 | - **destroy**: Call this method to destroy the Froala Editor
526 | - **getEditor**: Call this method to retrieve the editor that was created. This method will return *null* if the editor was not yet created
527 |
528 | ## Displaying HTML
529 |
530 | To display content created with the froala editor use the `FroalaEditorView` component.
531 |
532 | ```js
533 |
537 |
540 | ```
541 |
542 | #### Specific option for special tags
543 |
544 | * **reactIgnoreAttrs**: (default: null) This option is an array of attributes that you want to ignore when the editor updates the froalaModel:
545 |
546 | ```js
547 | config: {
548 | reactIgnoreAttrs: ['class', 'id']
549 | },
550 | ```
551 |
552 | ## Using type definition file
553 | `index.d.ts` file is the type definition file for this repository. It is placed inside lib folder.In order to use it in your code , use the following line:
554 | ```
555 | ///
556 | ```
557 | where path is the location of index.d.ts file.
558 |
559 |
560 | ### Custom Buttons
561 |
562 | You can pass the custom buttons to the editor by following way:
563 |
564 | ```javascript
565 |
601 |
602 | ```
603 | Now you can use these buttons in options:
604 | ```javascript
605 | toolbarButtons: [['undo', 'redo' , 'bold'], ['alert', 'clear', 'insert']],
606 |
607 | ```
608 |
609 | ## License
610 |
611 | The `react-froala-wyswiyg` project is under MIT license. However, in order to use Froala WYSIWYG HTML Editor plugin you should purchase a license for it.
612 |
613 | Froala Editor has [3 different licenses](http://froala.com/wysiwyg-editor/pricing) for commercial use.
614 | For details please see [License Agreement](http://froala.com/wysiwyg-editor/terms).
615 |
616 | ## Development environment setup
617 |
618 | If you want to contribute to react-froala-wyswiyg, you will first need to install the required tools to get the project going.
619 |
620 | #### Prerequisites
621 |
622 | * [Node Package Manager](https://npmjs.org/) (NPM)
623 | * [Git](http://git-scm.com/)
624 |
625 | #### Install dependencies
626 |
627 | $ npm install
628 |
629 | #### Build
630 |
631 | $ npm run build
632 |
633 | #### Run Demo
634 |
635 | $ npm run demo
636 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/configs/bs-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | server: {
3 | middleware: {
4 | // overrides the second middleware default with new settings
5 | 1: require('connect-history-api-fallback')({index: '/src/index.html', verbose: true})
6 | }
7 | }
8 | };
--------------------------------------------------------------------------------
/demo/src/basic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello React
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/demo/src/basic.jsx:
--------------------------------------------------------------------------------
1 | // Note that Froala Editor has to be required separately.
2 |
3 | import 'froala-editor/css/froala_editor.pkgd.min.css';
4 | import 'froala-editor/css/froala_style.css';
5 | import 'file-loader?name=[name].[ext]!./basic.html';
6 |
7 | import FroalaEditor from 'react-froala-wysiwyg';
8 | import React from 'react';
9 | import ReactDOM from 'react-dom/client';
10 |
11 | // Render Froala Editor component.
12 | const root = ReactDOM.createRoot(document.getElementById('editor'));
13 | root.render();
23 |
24 |
--------------------------------------------------------------------------------
/demo/src/custombutton.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello React
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/demo/src/custombutton.jsx:
--------------------------------------------------------------------------------
1 | import 'froala-editor/css/froala_editor.pkgd.min.css';
2 | import 'froala-editor/css/froala_style.css';
3 | import 'file-loader?name=[name].[ext]!./custombutton.html';
4 |
5 | import FroalaEditor from 'react-froala-wysiwyg';
6 | import React from 'react';
7 | import ReactDOM from 'react-dom/client';
8 | import Froalaeditor from 'froala-editor';
9 | Froalaeditor.DefineIcon('alert', {NAME: 'info', SVG_KEY: 'help'});
10 | Froalaeditor.RegisterCommand('alert', {
11 | title: 'Hello',
12 | focus: false,
13 | undo: false,
14 | refreshAfterCallback: false,
15 | callback: function () {
16 | alert('Hello!');
17 | }
18 | });
19 |
20 | Froalaeditor.DefineIcon('clear', {NAME: 'remove', SVG_KEY: 'remove'});
21 | Froalaeditor.RegisterCommand('clear', {
22 | title: 'Clear HTML',
23 | focus: false,
24 | undo: true,
25 | refreshAfterCallback: true,
26 | callback: function () {
27 | this.html.set('');
28 | this.events.focus();
29 | }
30 | });
31 |
32 | Froalaeditor.DefineIcon('insert', {NAME: 'plus', SVG_KEY: 'add'});
33 | Froalaeditor.RegisterCommand('insert', {
34 | title: 'Insert HTML',
35 | focus: true,
36 | undo: true,
37 | refreshAfterCallback: true,
38 | callback: function () {
39 | this.html.insert('My New HTML');
40 | }
41 | });
42 |
43 | // Render Froala Editor component.
44 | const root = ReactDOM.createRoot(document.getElementById('editor'));
45 | root.render();
--------------------------------------------------------------------------------
/demo/src/edit_inline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello React
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/demo/src/edit_inline.jsx:
--------------------------------------------------------------------------------
1 | // Note that Froala Editor has to be required separately
2 | import 'froala-editor/css/froala_editor.pkgd.min.css';
3 | import 'froala-editor/css/froala_style.css';
4 |
5 | import FroalaEditor from 'react-froala-wysiwyg';
6 | import React from 'react';
7 | import ReactDOM from 'react-dom/client';
8 |
9 | // Render Froala Editor component.
10 | class EditorComponent extends React.Component {
11 | constructor() {
12 | super();
13 |
14 | this.config = {
15 | placeholderText: 'Add a Title',
16 | charCounterCount: false,
17 | toolbarInline: true,
18 | events: {
19 | initialized: function() {
20 | console.log('initialized');
21 | }
22 | }
23 | };
24 |
25 | this.state = {
26 | myTitle: 'Click here to edit this text.'
27 | };
28 |
29 | this.handleModelChange = this.handleModelChange.bind(this);
30 | this.handleInputChange = this.handleInputChange.bind(this);
31 | }
32 |
33 | handleModelChange (model) {
34 | this.setState({
35 | myTitle: model
36 | })
37 | }
38 |
39 | handleInputChange (e) {
40 | this.setState({
41 | myTitle: e.target.value
42 | })
43 | }
44 |
45 | render () {
46 | return(
47 |