FlyEditor is a lightweight WYSIWYG web editor component designed for React environments.
It seamlessly supports switching between editing and viewer modes, file uploads, customizable toolbars, and more.
You can test the features and functionality of FlyEditor via the link below:
editable prop.onUploadImage, onUploadImages).insertImageSource).toolsH) and vertical (toolsV) toolbars.userFontFamilyList) and font sizes (userFontSizeList).useNoteLine to apply a ruled notebook background line style.lang), toolbar tooltips, auto-focus, and keyboard shortcut (Ctrl+S / Cmd+S) save callbacks.npm i flyeditor
Below is a basic example of using FlyEditor in a React component.
import React, { useState } from 'react';
import FlyEditor from 'flyeditor';
import 'flyeditor/dist/flyeditor.css';
const MyEditor = () => {
const [initContent, setInitContent] = useState('<p>Hello World!</p>');
const [content, setContent] = useState('');
const [isEditable, setIsEditable] = useState(true);
return (
<FlyEditor
value={initContent}
editable={isEditable}
onChange={setContent}
/>
);
};
export default MyEditor;
A simple way to save content entered into the editor.
import React, { useState } from 'react';
import FlyEditor from 'flyeditor';
import 'flyeditor/dist/flyeditor.css';
const MyEditor = () => {
const [initContent, setInitContent] = useState('<p>Hello World!</p>');
const [content, setContent] = useState('');
const [isEditable, setIsEditable] = useState(true);
// 1. Save manually via user button
const saveContent = async () => {
// Example: Call server API to save content
const formData = new FormData();
formData.append('content', content);
const res = await api.saveContent(formData);
console.log('Saved successfully.');
};
// 2. Triggered internally from the editor
const onSaveContent = async (htmlContent: string) => {
// Example: Call server API to save content
const formData = new FormData();
formData.append('content', htmlContent);
const res = await api.saveContent(formData);
console.log('Saved successfully.');
};
return (
<div>
<button onClick={saveContent}>Save</button>
<FlyEditor
value={initContent}
editable={isEditable}
onChange={setContent}
onSave={onSaveContent}
/>
</div>
);
};
export default MyEditor;
Integrate server upload logic using the onUploadImage prop.
import FlyEditor, { IImageAttr } from 'flyeditor';
...
const MyEditor = () => {
const [initContent, setInitContent] = useState('<p>Hello World!</p>');
const [content, setContent] = useState('');
// Single image upload handler
const handleUploadImage = async (file: File): Promise<IImageAttr> => {
// Example: Call server API for file upload
// const formData = new FormData();
// formData.append('file', file);
// const res = await api.upload(formData);
return {
url: 'https://example.com/images/sample.png',
name: file.name,
alt: 'Uploaded image',
};
};
// Apply component
return (
<FlyEditor
value={initContent}
editable={true}
onChange={setContent}
onUploadImage={handleUploadImage} // Single upload
// multiUploadImage={true} // Set to true for multiple uploads
// onUploadImages={handleUploadImages}
/>
);
...
}
Dynamically insert images into the editor using external state (insertImageSource). Reset state in the onImageInserted callback after completion.
...
const [imageSource, setImageSource] = useState<string | IImageAttr | null>(
null,
);
const insertImage = () => {
setImageSource({
url: 'https://example.com/flower.png',
name: 'flower',
alt: 'Flower image',
});
};
return (
<>
<button onClick={insertImage}>Insert Image</button>
<FlyEditor
value={initContent}
editable={true}
onChange={setContent}
insertImageSource={imageSource}
onImageInserted={() => setImageSource(null)} // Reset to null after processing (Required)
/>
</>
);
...
<FlyEditor
value={initContent}
editable={true}
useNoteLine={true} // Enable notebook line background mode
onChange={setContent}
onSave={html => console.log('Saved HTML:', html)}
/>
To display saved HTML content created with the editor, import flyeditor.css and use FlyView
import { FlyView } from 'flyeditor';
import 'flyeditor/dist/flyeditor.css';
...
const MyViewer = () => {
const [dbContent, setDbContent] = useState('');
useEffect(()=>{
// ex) server api
const res = await api.getContent();
setDbContent(res);
}, [])
return (
<div className="viewer-container">
<FlyView value={dbContent} />
</div>
);
...
}
List of main props supported by the FlyEditor component. (All props are optional and revert to default values if unspecified.)
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | '' | HTML content to be inserted into the editor |
editable | boolean | true | Sets Edit mode (true) or Viewer mode (false) |
onChange | (html: string) => void | - | Callback function called when content changes |
onSave | (html: string) => void | - | Callback called when clicking the Save button or pressing Ctrl+S (Cmd+S) |
autoFocus | boolean | true | Whether to auto-focus the editor upon mount |
lang | 'ko' | 'en' | Browser locale | Editor UI language setting |
useNoteLine | boolean | false | Whether to apply notebook line background style |
tooltip | boolean | true | Whether to show tooltips on toolbar icons |
className | string | - | Custom class name for the editor container |
insertImageSource | string | IImageAttr | null | null | Image data/URL injected externally into the editor |
onImageInserted | () => void | - | Reset callback executed after insertImageSource insertion completes |
onUploadImage | (file: File) => Promise<IImageAttr> | - | Single image file upload handler |
onUploadImages | (files: FileList) => Promise<IImageAttr[]> | - | Multiple image files upload handler (Used when multiUploadImage is true) |
multiUploadImage | boolean | false | Allows multiple file uploads |
dropUploadImage | boolean | true | Allows image uploads via Drag & Drop |
defaultFontSize | number | 15 | Default font size |
defaultFontFamily | string | Pretendard | Default font family |
userFontSizeList | number[] | Default set | List of font sizes displayed in toolbar dropdown |
userFontFamilyList | IFontFamilyInfo[] | Default set | List of custom font families displayed in toolbar dropdown |
toolsH | string[] | Default set | Horizontal toolbar item configuration |
toolsV | string[] | Default set | Vertical toolbar item configuration |
IImageAttrObject type used when inserting or returning uploaded images.
export interface IImageAttr {
url: string; // Accessible image URL (Required)
name?: string; // File name or identifier
alt?: string; // Alternative text (alt attribute)
}
IFontFamilyItemOption type for the font family selection dropdown.
export interface IFontFamilyInfo {
label: string; // Display name shown to the user
value: string; // Actual CSS font-family value
}
By utilizing toolsH and toolsV props, you can customize and layout only the required toolbar buttons.
fontsize, fontfamily, forecolor, backcolor cannot be placed here)<FlyEditor
toolsH={[
'save',
'history',
'fontsize',
'fontfamily',
'',
'forecolor',
'backcolor',
'',
'bold',
'italic',
'underline',
'strikethrough',
'',
'image',
'code',
'youtube',
]}
toolsV={[
'left',
'center',
'right',
'justify',
'',
'moveup',
'movedown',
'insertbefore',
'insertafter',
'indent',
'outdent',
'empty',
]}
/>
Complete list and descriptions of tool icons usable in toolsH and toolsV arrays.
Note: Inserting an empty string (
'') in the array adds aseparatorspace between toolbar icons. empty: If you putemptyin the array, an empty space the size of the default toolbar icon is inserted.
toolsH) - Text Formatting & Styles, Save, Image Insertion| Tool Key | Icon/Feature | Description |
|---|---|---|
save | Save | Executes onSave callback and passes the current editor HTML content. |
history | undo/redo | undo, redo button |
fontsize | Font Size | Provides a dropdown menu to change text size. |
fontfamily | Font Family | Provides a dropdown menu to change font family. |
forecolor | Text Color | Changes the text color of selected text. |
backcolor | Background Color | Changes the background / highlight color of selected text. |
bold | Bold | Toggles bold style on selected text. |
italic | Italic | Toggles italic style on selected text. |
underline | Underline | Toggles underline style on selected text. |
strikethrough | Strikethrough | Toggles strikethrough style on selected text. |
superscript | Superscript | Toggles superscript style on selected text. |
subscript | Subscript | Toggles subscript style on selected text. |
image | Insert Image | Opens file upload window for single/multiple images. |
code | Insert Source Code | Opens source code input modal. |
youtube | Insert YouTube | Opens YouTube video input modal (Enter YouTube share URL). |
toolsV) - Paragraph Formatting & Movement| Tool Key | Icon/Feature | Description |
|---|---|---|
left | Align Left | Aligns current paragraph or selected block to the left. |
center | Align Center | Aligns current paragraph or selected block to the center. |
right | Align Right | Aligns current paragraph or selected block to the right. |
justify | Justify | Justifies current paragraph or selected block. |
moveup | Move Up | Moves the currently focused paragraph above the previous paragraph. |
movedown | Move Down | Moves the currently focused paragraph below the next paragraph. |
insertbefore | Insert Line Above | Inserts a new empty paragraph above the current block. |
insertafter | Insert Line Below | Inserts a new empty paragraph below the current block. |
indent | Indent | Increases indentation for the current block. |
outdent | Outdent | Decreases indentation for the current block. |
MIT License