flyeditor
v1.6.3
Published
A lightweight react webeditor, flyeditor
Maintainers
Readme
FlyEditor
FlyEditor는 React 환경에서 간편하게 사용할 수 있는 위지윅(WYSIWYG) 웹에디터 컴포넌트입니다.
손쉽게 편집 및 뷰어 모드 전환, 파일 업로드, 커스텀 도구모음 등을 지원합니다.
에디터 미리보기
아래 링크에서 FlyEditor 의 동작 및 기능을 테스트해 보실 수 있습니다.

주요 기능 (Features)
- 자유로운 모드 전환:
editable속성을 통해 편집 모드와 읽기 전용(Viewer) 모드를 손쉽게 전환할 수 있습니다. - 다양한 이미지 업로드 방식 지원:
- 단일 및 다중 파일 업로드 콜백 지원 (
onUploadImage,onUploadImages) - 에디터 내 직접 드래그 앤 드롭(Drag & Drop) 업로드 지원
- 외부 상태(
insertImageSource)를 통한 동적 이미지 URL 직접 삽입 기능
- 단일 및 다중 파일 업로드 콜백 지원 (
- 자유로운 커스텀 툴바 (Toolbar): 가로(
toolsH) 및 세로(toolsV) 툴바 항목을 원하는 구성으로 자유롭게 배치 및 제한할 수 있습니다. - 커스텀 폰트 & 크기 설정: 기본 글꼴 및 크기 지정은 물론, 사용자가 사용할 폰트 목록(
userFontFamilyList)과 크기 목록(userFontSizeList)을 커스텀 정의할 수 있습니다. - 노트 줄 배경 모드:
useNoteLine옵션을 활성화하여 공책/노트 형태의 배경 라인 스타일을 적용할 수 있습니다. - 다국어 및 UX 편의기능: 한국어/영어 UI 언어 셋(
lang), 툴바 툴팁, 자동 포커스, 단축키(Ctrl+S/Cmd+S) 저장 콜백을 지원합니다.
설치 (Installation)
npm i flyeditor빠른 시작 (Quick Start)
가장 기본적인 형태로 FlyEditor를 사용하는 방법입니다.
import React, { useState } from 'react';
import FlyEditor from 'flyeditor';
import 'flyeditor/dist/flyeditor.css';
const MyEditor = () => {
const [initContent, setInitContent] = useState('<p>안녕하세요!</p>');
const [content, setContent] = useState('');
const [isEditable, setIsEditable] = useState(true);
return (
<FlyEditor
value={initContent}
editable={isEditable}
onChange={setContent}
/>
);
};
export default MyEditor;주요 예제 (Usage Examples)
1. 콘텐츠 저장
에디터에 입력된 내용을 저장하는 간단한 방법 입니다.
import React, { useState } from 'react';
import FlyEditor from 'flyeditor';
import 'flyeditor/dist/flyeditor.css';
const MyEditor = () => {
const [initContent, setInitContent] = useState('<p>안녕하세요!</p>');
const [content, setContent] = useState('');
const [isEditable, setIsEditable] = useState(true);
// 1. 사용자 버튼으로 직접 저장
const saveContent = async () => {
// 예시: 서버에 저장 처리 API 호출
const formData = new FormData();
formData.append('content', content);
const res = await api.saveContent(formData);
console.log('저장되었습니다.');
};
// 2. 에디터 내부에서 저장 실행 시
const onSaveContent = async (htmlContent: string) => {
// 예시: 서버에 저장 처리 API 호출
const formData = new FormData();
formData.append('content', htmlContent);
const res = await api.saveContent(formData);
console.log('저장되었습니다.');
};
return (
<div>
<button onClick={saveContent}>Save</button>
<FlyEditor
value={initContent}
editable={isEditable}
onChange={setContent}
onSave={onSaveContent}
/>
</div>
);
};
export default MyEditor;2. 이미지 업로드 처리 (단일)
onUploadImage 속성을 통해 서버 업로드 로직을 연동할 수 있습니다.
import FlyEditor, { IImageAttr } from 'flyeditor';
...
const MyEditor = () => {
const [initContent, setInitContent] = useState('<p>안녕하세요!</p>');
const [content, setContent] = useState('');
// 단일 이미지 업로드 핸들러
const handleUploadImage = async (file: File): Promise<IImageAttr> => {
// 예시: 서버 업로드 처리 API 호출
// 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: '업로드 이미지',
};
};
// 컴포넌트 적용
return (
<FlyEditor
value={initContent}
editable={true}
onChange={setContent}
onUploadImage={handleUploadImage} // 단일 업로드
// multiUploadImage={true} // 다중 업로드 사용 시 true
// onUploadImages={handleUploadImages}
/>
);
...
}3. 외부 버튼을 통한 이미지 URL 직접 삽입
외부 상태(insertImageSource)를 통해 에디터 내부에 이미지를 동적으로 삽입할 수 있습니다. 삽입 완료 후 onImageInserted 콜백에서 상태를 초기화합니다.
...
const [imageSource, setImageSource] = useState<string | IImageAttr | null>(
null,
);
const insertImage = () => {
setImageSource({
url: 'https://example.com/flower.png',
name: 'flower',
alt: '꽃 이미지',
});
};
return (
<>
<button onClick={insertImage}>이미지 삽입</button>
<FlyEditor
value={initContent}
editable={true}
onChange={setContent}
insertImageSource={imageSource}
onImageInserted={() => setImageSource(null)} // 처리 후 null로 리셋 필수
/>
</>
);
...4. 콘텐츠 뷰어 설정
에디터에서 작성된 html 콘텐츠를 저장 후 보여주는 화면에서는 아래와 같이 사용 합니다.
(flyeditor.css 를 삽입하고, 뷰 앨리먼트에 FlyView 콤포넌트 추가)
import { FlyView } from 'flyeditor';
import 'flyeditor/dist/flyeditor.css';
...
const MyViewer = () => {
const [dbContent, setDbContent] = useState('');
useEffect(()=>{
// 예시: 서버 데이터 조회 API 호출
const res = await api.getContent();
setDbContent(res);
}, [])
return (
<div className="my-viewer-container">
<FlyView value={dbContent} />
</div>
);
...
}FlyEditor Props API Reference
FlyEditor 컴포넌트에서 지원하는 주요 속성 목록입니다. (모든 항목은 선택 옵션이며 설정하지 않으면 기본값으로 동작 합니다.)
| Prop | Type | Default | 설명 |
| :----------------------- | :------------------------------------------- | :-------------- | :----------------------------------------------------------------------------------- |
| id | string | - | 에디터에 컨테이너에 설정할 고유 ID |
| value | string | '' | 에디터에 삽입될 콘텐츠 (HTML) |
| editable | boolean | true | 편집 모드(true) 또는 뷰어 모드(false) 설정 |
| onChange | (html: string) => void | - | 컨텐츠 변경 시 호출되는 콜백 함수 |
| onSave | (html: string) => void | - | 저장 버튼을 클릭 하거나 키보드 ctrl + s (mac: cmd + s) 입력시 호출되는 콜백 함수 |
| autoFocus | boolean | true | 에디터에 자동 포커스 여부 |
| lang | 'ko' \| 'en' | 브라우저 언어셋 | 에디터 UI 언어 설정 |
| useNoteLine | boolean | false | 에디터 배경에 노트 줄 스타일 적용 여부 |
| tooltip | boolean | true | 툴바 아이콘에 말풍선 툴팁 표시 여부 |
| tooltipPos | top \| bottom | top | 말풍선 툴팁의 위치 지정 (툴바의 상/하) |
| insertImageSource | string \| IImageAttr \| null | null | 에디터에 외부에서 주입할 이미지 정보 |
| onImageInserted | () => void | - | insertImageSource를 통한 이미지 삽입 완료 후 실행할 리셋 콜백 |
| onUploadImage | (file: File) => Promise<IImageAttr> | - | 단일 이미지 파일 업로드 핸들러 |
| onUploadImages | (files: FileList) => Promise<IImageAttr[]> | - | 다중 이미지 파일 업로드 핸들러 (multiUploadImage 가 true 인경우 사용) |
| multiUploadImage | boolean | false | 다중 파일 업로드 허용 여부 |
| dropUploadImage | boolean | true | 드래그 앤 드롭을 통한 이미지 업로드 허용 여부 |
| defaultFontSize | number | 15 | 기본 글자 크기 지정 (7 ~ 300 사이의 값) |
| defaultFontFamily | string | Pretendard | 기본 글자 모양 지정 |
| defaultLineHeight | number | 1.8 | 기본 문단 행 간격 지정 (1 ~ 3 사이의 값) |
| userFontSizeList | number[] | 기본셋 | 툴바 콤보박스에 표시할 폰트 크기 목록 (7 ~ 300 사이의 값을 가진 목록) |
| userFontFamilyList | IFontFamilyInfo[] | 기본셋 | 툴바 콤보박스에 표시할 커스텀 폰트 목록 |
| userLineHeightList | number[] | 기본셋 | 툴바 콤보박스에 표시할 행간 크기 목록 (1 ~ 3 사이의 값을 가진 목록) |
| userClassName | string | - | 에디터 컨테이너에 설정할 사용자 css className |
| toolsH | string[] | 기본셋 | 가로 툴바 배치 항목 설정 |
| toolsV | string[] | 기본셋 | 세로 툴바 배치 항목 설정 |
인터페이스 (Interfaces)
IImageAttr
이미지 삽입 및 업로드 반환 시 사용되는 객체 타입입니다.
export interface IImageAttr {
url: string; // 이미지 접근 가능한 URL (필수)
name?: string; // 파일명 또는 식별용 이름
alt?: string; // 대체 텍스트 (alt 속성)
}IFontFamilyItem
폰트 선택 드롭다운 옵션 타입입니다.
export interface IFontFamilyInfo {
label: string; // 사용자 화면에 표시될 이름
value: string; // 실제 CSS font-family 값
}FlyEditor Custom Toolbar Configuration
toolsH 및 toolsV 속성을 활용하면 필요한 버튼만 커스텀하여 툴바를 배치할 수 있습니다.
toolsH및toolsV항목을 설정하지 않으면 전체 툴바가 모두 삽입되며, 빈 배열([]) 을 할당하면 해당 툴바 영역 자체가 제거됩니다.
- toolsH : 가로 배치형 툴바
- toolsV : 세로 배치형 툴바
- 모든 툴바는 가로/세로에 자유롭게 배치 가능하나, 예외적으로
fontsize,fontfamily,letterspacing,lineheight항목은 가로 배치만 가능합니다.
<FlyEditor
toolsH={[
'save',
'history',
'fontsize',
'fontfamily',
.
.
.
]}
toolsV={[
'left',
'center',
'right',
'justify',
.
.
.
]}
/>FlyEditor Toolbar Items Reference
toolsH 및 toolsV 옵션 배열에 사용할 수 있는 전체 툴 아이콘 목록 및 설명입니다.
1. 가로 툴바 (toolsH) - 글자 서식 및 스타일, 저장, 이미지 삽입
| Tool Key | 아이콘/기능명 | 설명 |
| :------------------ | :-------------------- | :----------------------------------------------------------------------------- |
| save | 저장 | onSave 콜백 함수를 실행하여 현재 에디터 컨텐츠(html)를 전달합니다. |
| history | 실행취소/재실행 | 실행취소, 재실행을 할수 있는 버튼을 제공합니다. |
| fontsize | 글자 크기 | 텍스트의 크기를 변경하는 메뉴를 제공합니다. |
| fontfamily | 글자 모양 | 텍스트의 폰트종류를 변경하는 메뉴를 제공합니다. |
| letterspacing | 자간 | 선택한 텍스트의 글자 간격을 변경하는 메뉴를 제공합니다. |
| lineheight | 행간 | 현재 커서위치나 선택한 문단의 행 간격을 변경하는 메뉴를 제공합니다. |
| forecolor | 글자 색상 | 선택한 텍스트의 글자 색상(Color)을 변경합니다. |
| backcolor | 배경 색상 | 선택한 텍스트의 배경/형광펜 색상(Background Color)을 변경합니다. |
| bold | 굵게 | 선택한 텍스트를 굵은 글씨로 설정하거나 해제합니다. |
| italic | 기울임 | 선택한 텍스트를 이탤릭체로 설정하거나 해제합니다. |
| underline | 밑줄 | 선택한 텍스트에 밑줄을 적용하거나 해제합니다. |
| strikethrough | 취소선 | 선택한 텍스트에 취소선을 적용하거나 해제합니다. |
| superscript | 위 첨자 | 선택한 텍스트를 위 첨자로 변경하거나 해제합니다. |
| subscript | 아래 첨자 | 선택한 텍스트를 아래 첨자로 변경하거나 해제합니다. |
| table | 표 | 현재 커서위치에 표를 삽입합니다. 2개의 아이콘(표생성, 표스타일 )이 생성됩니다. |
| image | 이미지 | 단일/다중 이미지 파일 업로드 창을 호출합니다. |
| imagelink | 이미지 링크 | 이미지 url을 입력하여 이미지를 삽입합니다. |
| code | 소스 코드 | 소스 코드 입력 창을 호출합니다. |
| youtube | 유큐브 | 유튜브 영상 입력 창을 호출합니다.(유튜브 공유URL 입력) |
| hr | 수평선 | 현재 커서위치에 수평선을 삽입합니다. |
| unorderedlist | 순서 없는 목록 스타일 | 현재 커서위치의 문단에 순서 없는 목록 스타일을 적용합니다. |
| orderedlist | 순서 있는 목록 스타일 | 현재 커서위치의 문단에 순서 있는 목록 스타일을 적용합니다. |
2. 세로 툴바 (toolsV) - 문단 서식 및 이동
| Tool Key | 아이콘/기능명 | 설명 |
| :----------------- | :------------- | :--------------------------------------------------------------------------------------------------------- |
| left | 왼쪽 정렬 | 현재 포커스된 문단 또는 선택된 블록 (이미지, 코드, 유튜브, 표, 수평선) 을 왼쪽으로 정렬합니다. |
| center | 가운데 정렬 | 현재 포커스된 문단 또는 선택된 블록을 가운데로 정렬합니다. |
| right | 오른쪽 정렬 | 현재 포커스된 문단 또는 선택된 블록을 오른쪽으로 정렬합니다. |
| justify | 양쪽 정렬 | 현재 포커스된 문단을 양쪽으로 정렬 합니다. |
| indent | 들여쓰기 | 현재 포커스된 문단의 들여쓰기를 증가시킵니다. |
| outdent | 내어쓰기 | 현재 포커스된 문단의 들여쓰기를 감소시킵니다. |
| moveup | 위로 이동 | 현재 포커스된 문단이나 선택된 블록을 바로 이전 문단 위로 이동시킵니다. |
| movedown | 아래로 이동 | 현재 포커스된 문단이나 선택된 블록을 바로 다음 문단 아래로 이동시킵니다. |
| insertbefore | 위에 줄 추가 | 현재 포커스된 문단이나 선택된 블록 위쪽에 새로운 빈 문단을 삽입합니다. |
| insertafter | 아래에 줄 추가 | 현재 포커스된 문단이나 선택된 블록 아래쪽에 새로운 빈 문단을 삽입합니다. |
| eraser | 문단 지우개 | 현재 포커스된 문단이나 선택된 블록을 삭제합니다. |
3. 부가 툴바 - 특별한 기능이 없는 툴바 입니다. 툴바 레이아웃 조정을 위해 사용됩니다.
| Tool Key | 아이콘/기능명 | 설명 |
| :---------- | :--------------- | :----------------------------------------------------------- |
| '' | 작은 간격 띄우기 | 약간의 간격(7px)을 띄웁니다. |
| empty | 큰 간격 띄우기 | 툴바 1개 만큼의 간격(40px)을 띄웁니다. |
| / | 툴바행 분리 | 툴바 행을 분리하여 새 툴바 행을 만듭니다. (가로 툴바만 적용) |
FlyView Props API Reference
FlyView 컴포넌트에서 지원하는 주요 속성 목록입니다. (value 는 필수 항목이며, 그외 모든 항목은 선택 옵션입니다.)
| Prop | Type | Default | 설명 |
| :---------------------------- | :-------------------- | :----------- | :------------------------------------------------- |
| value 필수 | string | '' | 뷰어에 삽입될 콘텐츠 (HTML) |
| defaultFontSize | number | 15 | 기본 글자 크기 지정 (7 ~ 300 사이의 숫자) |
| defaultFontFamily | string | Pretendard | 기본 글자 모양 지정 |
| defaultLineHeight | number | 1.8 | 기본 문단 행 간격 지정 (1 ~ 3 사이의 숫자) |
| userClassName | string | - | 뷰어 컨테이너에 추가로 삽입할 사용자 css className |
| autoLink | boolean | true | 콘텐츠내 url 자동링크 |
| autoLinkTarget | '_blank' \| '_self' | _self | 콘텐츠내 url 자동링크 타겟 |
License
MIT License
