@zm-editor/react 0.1.0 → 0.1.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ko.md ADDED
@@ -0,0 +1,260 @@
1
+ # @zm-editor/react
2
+
3
+ [Tiptap](https://tiptap.dev) 기반의 Notion 스타일 리치 텍스트 에디터 React 컴포넌트입니다.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@zm-editor/react.svg)](https://www.npmjs.com/package/@zm-editor/react)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ [English](./README.md) | **한국어**
9
+
10
+ ## 주요 기능
11
+
12
+ - **Notion 스타일 UX** - 슬래시 명령어, 버블 메뉴, 드래그 앤 드롭 블록
13
+ - **35+ 슬래시 명령어** - 제목, 목록, 코드 블록, 테이블 등
14
+ - **28+ 커스텀 블록** - 이미지, 임베드, 콜아웃, 다이어그램, API 블록 등
15
+ - **구문 강조** - 26개 이상 언어 지원 (GitHub Dark 테마)
16
+ - **Mermaid 다이어그램** - 플로우차트, 시퀀스 다이어그램, 마인드맵
17
+ - **수학 수식** - KaTeX LaTeX 렌더링
18
+ - **다국어 지원** - 한국어 & 영어 내장
19
+ - **다크 모드** - 완전한 다크 모드 지원
20
+ - **TypeScript** - 완전한 타입 정의 포함
21
+
22
+ ## 설치
23
+
24
+ ```bash
25
+ npm install @zm-editor/core @zm-editor/react
26
+ ```
27
+
28
+ ### 필수 의존성
29
+
30
+ ```bash
31
+ npm install react react-dom
32
+ ```
33
+
34
+ ### 선택적 의존성
35
+
36
+ ```bash
37
+ # Mermaid 다이어그램 (플로우차트, 시퀀스 다이어그램 등)
38
+ npm install mermaid
39
+
40
+ # 수학 수식 (LaTeX 렌더링)
41
+ npm install katex
42
+
43
+ # 파일 첨부의 PDF 미리보기
44
+ npm install pdfjs-dist
45
+
46
+ # HTML 새니타이징
47
+ npm install dompurify
48
+ ```
49
+
50
+ > **참고:** Mermaid와 KaTeX는 선택 사항입니다. 설치하지 않은 경우, 다이어그램이나 수식 블록 사용 시 설치 안내가 표시됩니다.
51
+
52
+ ## 빠른 시작
53
+
54
+ ```tsx
55
+ 'use client'; // Next.js App Router 필수
56
+
57
+ import { ZmEditor } from '@zm-editor/react';
58
+
59
+ export default function MyEditor() {
60
+ return (
61
+ <ZmEditor
62
+ initialContent="<p>안녕하세요!</p>"
63
+ onChange={(editor) => {
64
+ console.log(editor.getJSON());
65
+ }}
66
+ />
67
+ );
68
+ }
69
+ ```
70
+
71
+ ## Next.js 사용법
72
+
73
+ Next.js App Router에서는 SSR 문제를 피하기 위해 동적 import를 사용하세요:
74
+
75
+ ```tsx
76
+ 'use client';
77
+
78
+ import dynamic from 'next/dynamic';
79
+
80
+ const ZmEditor = dynamic(
81
+ () => import('@zm-editor/react').then((mod) => mod.ZmEditor),
82
+ { ssr: false }
83
+ );
84
+
85
+ export default function EditorWrapper() {
86
+ return <ZmEditor />;
87
+ }
88
+ ```
89
+
90
+ ## Props
91
+
92
+ | Prop | 타입 | 기본값 | 설명 |
93
+ |------|------|--------|------|
94
+ | `initialContent` | `string \| JSONContent` | `''` | 초기 에디터 콘텐츠 (HTML 또는 JSON) |
95
+ | `onChange` | `(editor: Editor) => void` | - | 콘텐츠 변경 시 콜백 |
96
+ | `onImageUpload` | `(file: File) => Promise<string>` | - | 커스텀 이미지 업로드 핸들러 |
97
+ | `locale` | `ZmEditorLocale` | `enLocale` | 다국어 설정 |
98
+ | `editable` | `boolean` | `true` | 편집 가능/불가 설정 |
99
+ | `placeholder` | `string` | - | 플레이스홀더 텍스트 |
100
+ | `className` | `string` | - | 추가 CSS 클래스 |
101
+
102
+ ## 슬래시 명령어
103
+
104
+ `/`를 입력하면 명령어 메뉴가 열립니다:
105
+
106
+ | 명령어 | 설명 |
107
+ |--------|------|
108
+ | `/text` | 일반 텍스트 |
109
+ | `/h1`, `/h2`, `/h3` | 제목 |
110
+ | `/bullet` | 글머리 기호 목록 |
111
+ | `/number` | 번호 목록 |
112
+ | `/task` | 할 일 목록 (체크리스트) |
113
+ | `/quote` | 인용문 |
114
+ | `/code` | 구문 강조 코드 블록 |
115
+ | `/table` | 테이블 (3x3) |
116
+ | `/image` | 이미지 업로드 |
117
+ | `/file` | 파일 첨부 |
118
+ | `/embed` | 임베드 (YouTube, CodeSandbox, StackBlitz, Replit) |
119
+ | `/callout` | 콜아웃 (info, warning, error, success, tip, note) |
120
+ | `/toggle` | 토글 (접기/펼치기) |
121
+ | `/mermaid` | Mermaid 다이어그램 |
122
+ | `/math` | 수학 수식 (LaTeX) |
123
+ | `/terminal` | 터미널 블록 |
124
+ | `/api` | API 요청/응답 블록 |
125
+ | `/divider` | 구분선 |
126
+ | `/toc` | 목차 |
127
+ | ... | 그 외 15개 이상 |
128
+
129
+ ## 다국어 설정 (i18n)
130
+
131
+ ```tsx
132
+ import { ZmEditor, koLocale, enLocale } from '@zm-editor/react';
133
+
134
+ // 한국어
135
+ <ZmEditor locale={koLocale} />
136
+
137
+ // 영어 (기본값)
138
+ <ZmEditor locale={enLocale} />
139
+
140
+ // 커스텀
141
+ <ZmEditor
142
+ locale={{
143
+ ...koLocale,
144
+ editor: {
145
+ placeholder: '내용을 입력하세요...',
146
+ },
147
+ }}
148
+ />
149
+ ```
150
+
151
+ ## 커스텀 이미지 업로드
152
+
153
+ ```tsx
154
+ <ZmEditor
155
+ onImageUpload={async (file) => {
156
+ const formData = new FormData();
157
+ formData.append('file', file);
158
+
159
+ const response = await fetch('/api/upload', {
160
+ method: 'POST',
161
+ body: formData,
162
+ });
163
+
164
+ const { url } = await response.json();
165
+ return url;
166
+ }}
167
+ />
168
+ ```
169
+
170
+ ## 콘텐츠 내보내기
171
+
172
+ ```tsx
173
+ import { useRef } from 'react';
174
+ import { ZmEditor, type ZmEditorRef } from '@zm-editor/react';
175
+
176
+ function MyEditor() {
177
+ const editorRef = useRef<ZmEditorRef>(null);
178
+
179
+ const handleExport = () => {
180
+ const editor = editorRef.current?.editor;
181
+ if (!editor) return;
182
+
183
+ const json = editor.getJSON(); // JSON 형식
184
+ const html = editor.getHTML(); // HTML 형식
185
+ const text = editor.getText(); // 텍스트 형식
186
+ };
187
+
188
+ return (
189
+ <>
190
+ <ZmEditor ref={editorRef} />
191
+ <button onClick={handleExport}>내보내기</button>
192
+ </>
193
+ );
194
+ }
195
+ ```
196
+
197
+ ## 테마 커스터마이징
198
+
199
+ ### 스타일 가져오기
200
+
201
+ ```tsx
202
+ import '@zm-editor/react/styles.css';
203
+ ```
204
+
205
+ ### CSS 변수로 커스터마이징
206
+
207
+ ```css
208
+ :root {
209
+ /* 기본 색상 */
210
+ --zm-colors-primary: #8b5cf6;
211
+ --zm-colors-primary-hover: #7c3aed;
212
+
213
+ /* 에디터 배경 & 텍스트 */
214
+ --zm-colors-editor-background: #ffffff;
215
+ --zm-colors-editor-text: #374151;
216
+ --zm-colors-editor-border: #e5e7eb;
217
+ }
218
+
219
+ /* 다크 모드 */
220
+ .dark,
221
+ [data-theme='dark'] {
222
+ --zm-colors-primary: #a78bfa;
223
+ --zm-colors-editor-background: #1f2937;
224
+ --zm-colors-editor-text: #d1d5db;
225
+ }
226
+ ```
227
+
228
+ ### 다크 모드 지원
229
+
230
+ zm-editor는 다음 방식의 다크 모드를 자동 지원합니다:
231
+ - `.dark` 클래스 (Tailwind CSS / next-themes)
232
+ - `[data-theme="dark"]` 속성
233
+ - `@media (prefers-color-scheme: dark)` 시스템 설정
234
+
235
+ ## 브라우저 지원
236
+
237
+ - Chrome (최신)
238
+ - Firefox (최신)
239
+ - Safari (최신)
240
+ - Edge (최신)
241
+
242
+ ## 요구 사항
243
+
244
+ - React 18+
245
+ - Node.js 18+
246
+
247
+ ## 관련 패키지
248
+
249
+ | 패키지 | 설명 |
250
+ |--------|------|
251
+ | [@zm-editor/core](https://www.npmjs.com/package/@zm-editor/core) | 코어 Tiptap 확장 및 유틸리티 |
252
+
253
+ ## 링크
254
+
255
+ - [GitHub 저장소](https://github.com/hanumoka/zm-editor)
256
+ - [문서](https://github.com/hanumoka/zm-editor#readme)
257
+
258
+ ## 라이선스
259
+
260
+ [MIT](https://github.com/hanumoka/zm-editor/blob/main/LICENSE)
package/README.md ADDED
@@ -0,0 +1,300 @@
1
+ # @zm-editor/react
2
+
3
+ React components for zm-editor - a Notion-style rich text editor built on [Tiptap](https://tiptap.dev).
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@zm-editor/react.svg)](https://www.npmjs.com/package/@zm-editor/react)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ **English** | [한국어](./README.ko.md)
9
+
10
+ ## Features
11
+
12
+ - **Notion-like UX** - Slash commands, bubble menu, drag & drop blocks
13
+ - **35+ Slash Commands** - Headings, lists, code blocks, tables, and more
14
+ - **28+ Custom Blocks** - Images, embeds, callouts, diagrams, API blocks, etc.
15
+ - **Syntax Highlighting** - 26+ languages with GitHub Dark theme
16
+ - **Mermaid Diagrams** - Flowcharts, sequence diagrams, mindmaps
17
+ - **Math Equations** - KaTeX LaTeX rendering
18
+ - **i18n Support** - English & Korean built-in
19
+ - **Dark Mode** - Full dark mode support
20
+ - **TypeScript** - Full type definitions included
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @zm-editor/core @zm-editor/react
26
+ ```
27
+
28
+ ### Peer Dependencies
29
+
30
+ ```bash
31
+ npm install react react-dom
32
+ ```
33
+
34
+ ### Optional Dependencies
35
+
36
+ ```bash
37
+ # For Mermaid diagrams (flowcharts, sequence diagrams, etc.)
38
+ npm install mermaid
39
+
40
+ # For Math equations (LaTeX rendering)
41
+ npm install katex
42
+
43
+ # For PDF preview in file attachments
44
+ npm install pdfjs-dist
45
+
46
+ # For HTML sanitization
47
+ npm install dompurify
48
+ ```
49
+
50
+ > **Note:** Mermaid and KaTeX are optional. If not installed, the editor will display a helpful installation prompt when you try to use diagram or math blocks.
51
+
52
+ ## Quick Start
53
+
54
+ ```tsx
55
+ 'use client'; // Required for Next.js App Router
56
+
57
+ import { ZmEditor } from '@zm-editor/react';
58
+
59
+ export default function MyEditor() {
60
+ return (
61
+ <ZmEditor
62
+ initialContent="<p>Hello, world!</p>"
63
+ onChange={(editor) => {
64
+ console.log(editor.getJSON());
65
+ }}
66
+ />
67
+ );
68
+ }
69
+ ```
70
+
71
+ ## Usage with Next.js
72
+
73
+ For Next.js App Router, use dynamic import to avoid SSR issues:
74
+
75
+ ```tsx
76
+ 'use client';
77
+
78
+ import dynamic from 'next/dynamic';
79
+
80
+ const ZmEditor = dynamic(
81
+ () => import('@zm-editor/react').then((mod) => mod.ZmEditor),
82
+ { ssr: false }
83
+ );
84
+
85
+ export default function EditorWrapper() {
86
+ return <ZmEditor />;
87
+ }
88
+ ```
89
+
90
+ ## Props
91
+
92
+ | Prop | Type | Default | Description |
93
+ |------|------|---------|-------------|
94
+ | `initialContent` | `string \| JSONContent` | `''` | Initial editor content (HTML or JSON) |
95
+ | `onChange` | `(editor: Editor) => void` | - | Callback when content changes |
96
+ | `onImageUpload` | `(file: File) => Promise<string>` | - | Custom image upload handler |
97
+ | `locale` | `ZmEditorLocale` | `enLocale` | Locale for i18n |
98
+ | `editable` | `boolean` | `true` | Enable/disable editing |
99
+ | `placeholder` | `string` | - | Placeholder text |
100
+ | `className` | `string` | - | Additional CSS class |
101
+
102
+ ## Slash Commands
103
+
104
+ Type `/` to open the command menu:
105
+
106
+ | Command | Description |
107
+ |---------|-------------|
108
+ | `/text` | Plain text paragraph |
109
+ | `/h1`, `/h2`, `/h3` | Headings |
110
+ | `/bullet` | Bullet list |
111
+ | `/number` | Numbered list |
112
+ | `/task` | Task list (checklist) |
113
+ | `/quote` | Blockquote |
114
+ | `/code` | Code block with syntax highlighting |
115
+ | `/table` | Table (3x3) |
116
+ | `/image` | Image upload |
117
+ | `/file` | File attachment |
118
+ | `/embed` | Embed (YouTube, CodeSandbox, StackBlitz, Replit) |
119
+ | `/callout` | Callout box (info, warning, error, success, tip, note) |
120
+ | `/toggle` | Toggle (collapsible content) |
121
+ | `/mermaid` | Mermaid diagram |
122
+ | `/math` | Math equation (LaTeX) |
123
+ | `/terminal` | Terminal block |
124
+ | `/api` | API request/response block |
125
+ | `/divider` | Horizontal rule |
126
+ | `/toc` | Table of contents |
127
+ | `/error` | Error/warning/info message |
128
+ | `/os` | OS-specific commands (macOS/Linux/Windows) |
129
+ | `/changelog` | Version changelog |
130
+ | `/env` | Environment variables (with masking) |
131
+ | `/gist` | GitHub Gist embed |
132
+ | `/diff` | Code diff block |
133
+ | `/footnote` | Footnote |
134
+ | `/log` | Log block (debug/info/warn/error) |
135
+ | `/stacktrace` | Stack trace block |
136
+ | `/metadata` | Document metadata |
137
+ | `/graphql` | GraphQL query block |
138
+ | `/openapi` | OpenAPI/Swagger embed |
139
+ | `/diagram` | PlantUML/D2 diagram |
140
+ | `/emoji` | Emoji picker |
141
+
142
+ ## Internationalization (i18n)
143
+
144
+ ```tsx
145
+ import { ZmEditor, koLocale, enLocale } from '@zm-editor/react';
146
+
147
+ // Korean
148
+ <ZmEditor locale={koLocale} />
149
+
150
+ // English (default)
151
+ <ZmEditor locale={enLocale} />
152
+
153
+ // Custom locale
154
+ <ZmEditor
155
+ locale={{
156
+ ...enLocale,
157
+ editor: {
158
+ placeholder: 'Start writing...',
159
+ },
160
+ }}
161
+ />
162
+ ```
163
+
164
+ ## Custom Image Upload
165
+
166
+ ```tsx
167
+ <ZmEditor
168
+ onImageUpload={async (file) => {
169
+ const formData = new FormData();
170
+ formData.append('file', file);
171
+
172
+ const response = await fetch('/api/upload', {
173
+ method: 'POST',
174
+ body: formData,
175
+ });
176
+
177
+ const { url } = await response.json();
178
+ return url;
179
+ }}
180
+ />
181
+ ```
182
+
183
+ ## Export Content
184
+
185
+ ```tsx
186
+ import { useRef } from 'react';
187
+ import { ZmEditor, type ZmEditorRef } from '@zm-editor/react';
188
+
189
+ function MyEditor() {
190
+ const editorRef = useRef<ZmEditorRef>(null);
191
+
192
+ const handleExport = () => {
193
+ const editor = editorRef.current?.editor;
194
+ if (!editor) return;
195
+
196
+ const json = editor.getJSON();
197
+ const html = editor.getHTML();
198
+ const text = editor.getText();
199
+ };
200
+
201
+ return (
202
+ <>
203
+ <ZmEditor ref={editorRef} />
204
+ <button onClick={handleExport}>Export</button>
205
+ </>
206
+ );
207
+ }
208
+ ```
209
+
210
+ ## Theming & Customization
211
+
212
+ zm-editor uses CSS custom properties (variables) for theming, making it easy to customize colors, spacing, and more.
213
+
214
+ ### Import Styles
215
+
216
+ ```tsx
217
+ // Import in your layout or global CSS
218
+ import '@zm-editor/react/styles.css';
219
+ ```
220
+
221
+ ### Customize with CSS Variables
222
+
223
+ Override CSS variables to customize the editor appearance:
224
+
225
+ ```css
226
+ /* In your global CSS */
227
+ :root {
228
+ /* Primary colors */
229
+ --zm-colors-primary: #8b5cf6;
230
+ --zm-colors-primary-hover: #7c3aed;
231
+
232
+ /* Editor background & text */
233
+ --zm-colors-editor-background: #ffffff;
234
+ --zm-colors-editor-text: #374151;
235
+ --zm-colors-editor-border: #e5e7eb;
236
+
237
+ /* Menu colors */
238
+ --zm-colors-menu-background: #ffffff;
239
+ --zm-colors-menu-hover: #f3f4f6;
240
+ --zm-colors-menu-selected: #eff6ff;
241
+ }
242
+
243
+ /* Dark mode */
244
+ .dark,
245
+ [data-theme='dark'] {
246
+ --zm-colors-primary: #a78bfa;
247
+ --zm-colors-editor-background: #1f2937;
248
+ --zm-colors-editor-text: #d1d5db;
249
+ --zm-colors-editor-border: #374151;
250
+ }
251
+ ```
252
+
253
+ ### Available CSS Variables
254
+
255
+ | Category | Variables |
256
+ |----------|-----------|
257
+ | **Editor** | `--zm-colors-editor-background`, `--zm-colors-editor-text`, `--zm-colors-editor-border`, `--zm-colors-heading` |
258
+ | **Menu** | `--zm-colors-menu-background`, `--zm-colors-menu-text`, `--zm-colors-menu-hover`, `--zm-colors-menu-selected` |
259
+ | **Primary** | `--zm-colors-primary`, `--zm-colors-primary-hover`, `--zm-colors-primary-text` |
260
+ | **Code** | `--zm-colors-code-background`, `--zm-colors-codeblock-background`, `--zm-colors-codeblock-text` |
261
+ | **Status** | `--zm-colors-success`, `--zm-colors-warning`, `--zm-colors-error`, `--zm-colors-info` |
262
+ | **Spacing** | `--zm-spacing-xs` (0.25rem), `--zm-spacing-sm` (0.5rem), `--zm-spacing-md` (1rem), `--zm-spacing-lg` (1.5rem) |
263
+ | **Radius** | `--zm-radius-sm` (4px), `--zm-radius-md` (6px), `--zm-radius-lg` (8px) |
264
+ | **Typography** | `--zm-font-family-sans`, `--zm-font-family-mono`, `--zm-font-size-*` |
265
+
266
+ See `variables.css` for the complete list of available variables.
267
+
268
+ ### Dark Mode Support
269
+
270
+ zm-editor automatically supports dark mode via:
271
+ - `.dark` class (Tailwind CSS / next-themes)
272
+ - `[data-theme="dark"]` attribute
273
+ - `@media (prefers-color-scheme: dark)` system preference
274
+
275
+ ## Browser Support
276
+
277
+ - Chrome (latest)
278
+ - Firefox (latest)
279
+ - Safari (latest)
280
+ - Edge (latest)
281
+
282
+ ## Requirements
283
+
284
+ - React 18+
285
+ - Node.js 18+
286
+
287
+ ## Related Packages
288
+
289
+ | Package | Description |
290
+ |---------|-------------|
291
+ | [@zm-editor/core](https://www.npmjs.com/package/@zm-editor/core) | Core Tiptap extensions and utilities |
292
+
293
+ ## Links
294
+
295
+ - [GitHub Repository](https://github.com/hanumoka/zm-editor)
296
+ - [Documentation](https://github.com/hanumoka/zm-editor#readme)
297
+
298
+ ## License
299
+
300
+ [MIT](https://github.com/hanumoka/zm-editor/blob/main/LICENSE)