eddyter 1.3.56 → 1.3.57

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.
Files changed (231) hide show
  1. package/LICENSE +24 -24
  2. package/README.md +493 -493
  3. package/dist/App.d.ts +3 -2
  4. package/dist/Provider/EditorProvider.d.ts +32 -31
  5. package/dist/Provider/LexicalProvider.d.ts +6 -5
  6. package/dist/api/ai/index.d.ts +39 -83
  7. package/dist/api/analytics.d.ts +21 -21
  8. package/dist/api/auth.d.ts +108 -108
  9. package/dist/api/bugReport.d.ts +27 -27
  10. package/dist/api/config/axios.d.ts +2 -1
  11. package/dist/api/config/endpoints.d.ts +24 -27
  12. package/dist/api/featureSuggestion.d.ts +23 -23
  13. package/dist/api/feedback.d.ts +26 -26
  14. package/dist/api/linkPreview.d.ts +15 -15
  15. package/dist/api/transcript/index.d.ts +68 -68
  16. package/dist/assets/style.css +1 -1
  17. package/dist/babel-1c4a328b.js +7478 -0
  18. package/dist/components/AiPlugin/index.d.ts +6 -6
  19. package/dist/components/AlignMenu/AlignMenu.d.ts +9 -8
  20. package/dist/components/AlignMenu/AlignMenuDrop.d.ts +3 -2
  21. package/dist/components/AlignMenu/index.d.ts +1 -1
  22. package/dist/components/AutoExpandingDemo.d.ts +6 -5
  23. package/dist/components/BlockFormatMenu/BlockFormatMenu.d.ts +3 -2
  24. package/dist/components/BlockFormatMenu/constants.d.ts +14 -14
  25. package/dist/components/BlockFormatMenu/index.d.ts +1 -1
  26. package/dist/components/BugReportDialog/index.d.ts +6 -6
  27. package/dist/components/ChartEditDialog.d.ts +9 -8
  28. package/dist/components/ChartInsertDialog.d.ts +8 -7
  29. package/dist/components/CodeActionMenuPlugin/components/CopyButton/index.d.ts +7 -6
  30. package/dist/components/CodeActionMenuPlugin/components/PrettierButton/index.d.ts +9 -8
  31. package/dist/components/CodeActionMenuPlugin/index.d.ts +5 -4
  32. package/dist/components/CodeActionMenuPlugin/utils.d.ts +1 -1
  33. package/dist/components/ColorPicker/ColorPicker.d.ts +3 -2
  34. package/dist/components/ColorPicker/index.d.ts +1 -1
  35. package/dist/components/CommentSidebar/CommentSidebar.d.ts +8 -7
  36. package/dist/components/CommentSidebar/index.d.ts +1 -1
  37. package/dist/components/CommentToggle/CommentToggle.d.ts +8 -7
  38. package/dist/components/CommentToggle/index.d.ts +1 -1
  39. package/dist/components/CommentView/CommentView.d.ts +9 -8
  40. package/dist/components/CommentView/index.d.ts +1 -1
  41. package/dist/components/ConfigurableEditorWithAuth.d.ts +35 -34
  42. package/dist/components/ContentPreview/index.d.ts +37 -36
  43. package/dist/components/DatePicker/DatePickerWidget.d.ts +7 -6
  44. package/dist/components/EmojiPickerWidget/EmojiPickerWidget.d.ts +3 -2
  45. package/dist/components/EmojiPickerWidget/index.d.ts +1 -1
  46. package/dist/components/FeatureSuggestionDialog/index.d.ts +6 -6
  47. package/dist/components/FeedbackDialog/index.d.ts +7 -7
  48. package/dist/components/FileUpload/InsertFileDialog.d.ts +7 -7
  49. package/dist/components/FileUpload/InsertFileUploadedDialogBody.d.ts +5 -4
  50. package/dist/components/FileView/index.d.ts +9 -8
  51. package/dist/components/FloatingHighlightColorPicker/index.d.ts +9 -8
  52. package/dist/components/FontFamilySelect/FontFamilyMenu.d.ts +7 -6
  53. package/dist/components/FontSizePicker/FontSizeControl.d.ts +3 -2
  54. package/dist/components/FormatTextMenu/FormatTextMenu.d.ts +3 -2
  55. package/dist/components/FormatTextMenu/FormatTextMenuDrop.d.ts +3 -2
  56. package/dist/components/FormatTextMenu/index.d.ts +1 -1
  57. package/dist/components/HighlightColorPicker/HighlightColorPicker.d.ts +7 -6
  58. package/dist/components/HtmlViewDisplay.d.ts +3 -2
  59. package/dist/components/ImageComparisonDialog/index.d.ts +11 -10
  60. package/dist/components/ImageGenerationDialog/ImageGenerationManager.d.ts +11 -10
  61. package/dist/components/ImageGenerationDialog/index.d.ts +11 -10
  62. package/dist/components/ImageInsertTest.d.ts +3 -2
  63. package/dist/components/ImageView/ImageDialog/ImageUploadDialogBody.d.ts +9 -8
  64. package/dist/components/ImageView/ImageDialog/index.d.ts +6 -5
  65. package/dist/components/ImageView/ImageResizer.d.ts +16 -15
  66. package/dist/components/ImageView/index.d.ts +17 -16
  67. package/dist/components/InsertMenu/InsertMenu.d.ts +9 -8
  68. package/dist/components/InsertMenu/InsertMenuDrop.d.ts +9 -8
  69. package/dist/components/InsertMenu/index.d.ts +1 -1
  70. package/dist/components/LanguageSelectorDialog/index.d.ts +8 -7
  71. package/dist/components/LinkPreviewHover/index.d.ts +40 -40
  72. package/dist/components/NotePanelMenu/NotePanelMenu.d.ts +6 -5
  73. package/dist/components/NotePanelMenu/index.d.ts +1 -1
  74. package/dist/components/NotePanelView/NotePanelView.d.ts +9 -8
  75. package/dist/components/NotePanelView/index.d.ts +1 -1
  76. package/dist/components/Placeholder/Placeholder.d.ts +3 -2
  77. package/dist/components/Placeholder/index.d.ts +1 -1
  78. package/dist/components/Placeholder/styles.d.ts +1 -1
  79. package/dist/components/PreviewDialog/index.d.ts +10 -0
  80. package/dist/components/ScopedEditor.d.ts +8 -8
  81. package/dist/components/SignatureCaption/index.d.ts +6 -5
  82. package/dist/components/SpeechLanguageSelector/index.d.ts +9 -8
  83. package/dist/components/TableColorPicker/index.d.ts +8 -7
  84. package/dist/components/TableModal/TableModal.d.ts +10 -9
  85. package/dist/components/TextEnhanceDialog/index.d.ts +10 -9
  86. package/dist/components/ToneAdjustDialog/index.d.ts +8 -7
  87. package/dist/components/Toolbar/Toolbar.d.ts +3 -2
  88. package/dist/components/Toolbar/index.d.ts +1 -1
  89. package/dist/components/Toolbar/styles.d.ts +6 -6
  90. package/dist/components/VoiceTranscriptIcon/VoiceTranscriptIcon.d.ts +2 -1
  91. package/dist/components/VoiceTranscriptIcon/index.d.ts +1 -1
  92. package/dist/components/ui/avatar.d.ts +6 -6
  93. package/dist/components/ui/badge.d.ts +9 -8
  94. package/dist/components/ui/button.d.ts +11 -10
  95. package/dist/components/ui/calendar.d.ts +8 -7
  96. package/dist/components/ui/card.d.ts +8 -8
  97. package/dist/components/ui/checkbox.d.ts +4 -4
  98. package/dist/components/ui/dialog.d.ts +19 -19
  99. package/dist/components/ui/dropdown-menu.d.ts +27 -27
  100. package/dist/components/ui/input.d.ts +3 -3
  101. package/dist/components/ui/label.d.ts +4 -4
  102. package/dist/components/ui/popover.d.ts +7 -7
  103. package/dist/components/ui/select.d.ts +13 -13
  104. package/dist/components/ui/separator.d.ts +4 -4
  105. package/dist/components/ui/sheet.d.ts +24 -24
  106. package/dist/components/ui/skeleton.d.ts +3 -3
  107. package/dist/components/ui/tabs.d.ts +7 -7
  108. package/dist/components/ui/textarea.d.ts +3 -3
  109. package/dist/components/ui/tooltip.d.ts +7 -7
  110. package/dist/constants.d.ts +22 -21
  111. package/dist/context/CommentContext.d.ts +43 -42
  112. package/dist/context/HtmlViewContext.d.ts +17 -16
  113. package/dist/context/ToolbarContext.d.ts +56 -55
  114. package/dist/editorConfig.d.ts +70 -70
  115. package/dist/estree-2cbea43c.js +4667 -0
  116. package/dist/hooks/useAutoExpandingHeight.d.ts +15 -15
  117. package/dist/hooks/useBlockFormat.d.ts +17 -16
  118. package/dist/hooks/useColorPicker.d.ts +6 -6
  119. package/dist/hooks/useCustomCommands.d.ts +3 -2
  120. package/dist/hooks/useDebounce.d.ts +1 -1
  121. package/dist/hooks/useEditorToolbar.d.ts +10 -9
  122. package/dist/hooks/useFeedbackEligibility.d.ts +18 -18
  123. package/dist/hooks/useInsertMenu.d.ts +9 -9
  124. package/dist/hooks/useModal.d.ts +5 -5
  125. package/dist/hooks/useReactNativeBridge.d.ts +54 -54
  126. package/dist/hooks/useS3Uploader.d.ts +21 -21
  127. package/dist/hooks/useVoiceToText.d.ts +20 -20
  128. package/dist/html-c18fb60e.js +2841 -0
  129. package/dist/{html2pdf.bundle-5eb394ee.js → html2pdf.bundle-065f580a.js} +1 -1
  130. package/dist/{html2pdf.bundle.min-31a8b0db.js → html2pdf.bundle.min-c9c3c4f0.js} +1 -1
  131. package/dist/{index-66d9f716.js → index-39aec401.js} +14744 -16369
  132. package/dist/{index-953fe9ad.js → index-5b27923c.js} +4 -3
  133. package/dist/{index-969008d4.js → index-a9f00b0b.js} +47 -46
  134. package/dist/index.d.ts +14 -14
  135. package/dist/index.js +14 -13
  136. package/dist/lib/utils.d.ts +2 -1
  137. package/dist/main.d.ts +1 -0
  138. package/dist/markdown-39c3822b.js +3547 -0
  139. package/dist/nodes/ChartNode.d.ts +41 -40
  140. package/dist/nodes/CommentNode.d.ts +34 -33
  141. package/dist/nodes/CommentedTextNode.d.ts +29 -28
  142. package/dist/nodes/EmbedNode.d.ts +32 -31
  143. package/dist/nodes/FileNode.d.ts +33 -32
  144. package/dist/nodes/ImageNode.d.ts +65 -64
  145. package/dist/nodes/MentionNode.d.ts +75 -74
  146. package/dist/nodes/NotePanelNode.d.ts +31 -30
  147. package/dist/nodes/UploadingFileNode.d.ts +30 -29
  148. package/dist/nodes/UploadingImageNode.d.ts +30 -29
  149. package/dist/pages/ConfigurableEditor/ConfigurableEditor.d.ts +25 -24
  150. package/dist/pages/ConfigurableEditor/index.d.ts +2 -2
  151. package/dist/pages/NotFound.d.ts +2 -2
  152. package/dist/pages/RichTextEditor.d.ts +6 -6
  153. package/dist/pages/TextareaEditor.d.ts +6 -6
  154. package/dist/pages/styles.d.ts +5 -5
  155. package/dist/plugins/AIChatPlugin.d.ts +11 -10
  156. package/dist/plugins/AndroidKeyboardFixPlugin.d.ts +16 -16
  157. package/dist/plugins/AutocompletePlugin.d.ts +22 -22
  158. package/dist/plugins/CodeBlockNormalizerPlugin.d.ts +8 -8
  159. package/dist/plugins/CodeBlockSelectAllPlugin.d.ts +8 -8
  160. package/dist/plugins/CodeHighlightPlugin.d.ts +3 -2
  161. package/dist/plugins/CombinedAutocompletGrammarPlugin.d.ts +21 -20
  162. package/dist/plugins/CommentBubblePlugin.d.ts +3 -2
  163. package/dist/plugins/CommentPlugin.d.ts +7 -6
  164. package/dist/plugins/CustomHorizontalRulePlugin/CustomHorizontalRuleNode.d.ts +29 -28
  165. package/dist/plugins/CustomHorizontalRulePlugin/CustomHorizontalRulePlugin.d.ts +3 -3
  166. package/dist/plugins/CustomHorizontalRulePlugin/HorizontalRuleCustomizationDialog.d.ts +7 -6
  167. package/dist/plugins/CustomHorizontalRulePlugin/index.d.ts +3 -3
  168. package/dist/plugins/DragDropPastePlugin/index.d.ts +8 -8
  169. package/dist/plugins/DragDropPastePlugin/indexs.d.ts +1 -1
  170. package/dist/plugins/DraggableBlockPlugin/index.d.ts +4 -0
  171. package/dist/plugins/EmbedPreviewPlugin/FloatingEmbedMenuPlugin.d.ts +4 -3
  172. package/dist/plugins/EmbedPreviewPlugin/index.d.ts +6 -5
  173. package/dist/plugins/FilePlugin.d.ts +8 -7
  174. package/dist/plugins/FloatingLinkEditorPlugin/index.d.ts +6 -5
  175. package/dist/plugins/FloatingTextFormatToolbarPlugin/index.d.ts +27 -26
  176. package/dist/plugins/GrammarCheckPlugin.d.ts +2 -1
  177. package/dist/plugins/HtmlCodeViewPlugin/index.d.ts +2 -2
  178. package/dist/plugins/HtmlImportPlugin.d.ts +5 -5
  179. package/dist/plugins/HtmlSyncPlugin.d.ts +3 -3
  180. package/dist/plugins/ImagePlugin.d.ts +7 -6
  181. package/dist/plugins/LinkPlugin/index.d.ts +6 -5
  182. package/dist/plugins/LinkPreviewPlugin/index.d.ts +4 -4
  183. package/dist/plugins/LocalStoragePlugin.d.ts +7 -6
  184. package/dist/plugins/MarkdownShortcutsPlugin/index.d.ts +20 -20
  185. package/dist/plugins/MentionsPlugin/index.d.ts +7 -6
  186. package/dist/plugins/NotePanelPlugin.d.ts +7 -6
  187. package/dist/plugins/PasteOptionsPlugin/index.d.ts +17 -17
  188. package/dist/plugins/RichTextPastePlugin/index.d.ts +6 -5
  189. package/dist/plugins/SignatureCanvasPlugin/SignatureCanvasDialog.d.ts +6 -5
  190. package/dist/plugins/SignatureCanvasPlugin/SignatureCanvasPlugin.d.ts +9 -9
  191. package/dist/plugins/SignatureCanvasPlugin/index.d.ts +2 -2
  192. package/dist/plugins/SlashCommandPlugin/index.d.ts +2 -2
  193. package/dist/plugins/TableActionMenuPlugin/index.d.ts +6 -5
  194. package/dist/plugins/TableCellResizer/index.d.ts +2 -1
  195. package/dist/plugins/TableHoverActionsPlugin/index.d.ts +4 -4
  196. package/dist/plugins/TablePlugin.d.ts +5 -4
  197. package/dist/plugins/Tableimageautoresizeplugin.d.ts +1 -1
  198. package/dist/plugins/TextEnhancePlugin.d.ts +6 -6
  199. package/dist/plugins/TreeViewPlugin.d.ts +3 -2
  200. package/dist/plugins/UsageTrackingPlugin.d.ts +15 -15
  201. package/dist/plugins/VoiceTranscriptPlugin.d.ts +25 -25
  202. package/dist/plugins/WordCountPlugin.d.ts +3 -2
  203. package/dist/postcss-bbcc713e.js +5151 -0
  204. package/dist/services/chartService.d.ts +19 -18
  205. package/dist/standalone-36ad3877.js +2600 -0
  206. package/dist/styles/PlaygroundEditorTheme.d.ts +3 -2
  207. package/dist/types.d.ts +205 -203
  208. package/dist/typescript-39d06710.js +13533 -0
  209. package/dist/ui/ColorPicker.d.ts +14 -13
  210. package/dist/ui/Icons.d.ts +84 -84
  211. package/dist/ui/TextInput.d.ts +11 -10
  212. package/dist/utils/dateFormats.d.ts +33 -33
  213. package/dist/utils/debounce.d.ts +6 -5
  214. package/dist/utils/editorStyleConverter.d.ts +17 -16
  215. package/dist/utils/export.d.ts +2 -1
  216. package/dist/utils/getDOMRangeRect.d.ts +13 -13
  217. package/dist/utils/getSelectedNode.d.ts +3 -2
  218. package/dist/utils/helper.d.ts +3 -3
  219. package/dist/utils/index.d.ts +4 -3
  220. package/dist/utils/invarient.d.ts +1 -1
  221. package/dist/utils/setFloatingElemPosition.d.ts +8 -8
  222. package/dist/utils/setFloatingElemPositionForLinkEditor.d.ts +1 -1
  223. package/dist/utils/url.d.ts +9 -9
  224. package/package.json +149 -149
  225. package/dist/babel-2d5b260f.js +0 -7770
  226. package/dist/estree-28f5912a.js +0 -4920
  227. package/dist/html-3f297a3a.js +0 -3021
  228. package/dist/markdown-08edd93b.js +0 -3625
  229. package/dist/postcss-0e22bc25.js +0 -5187
  230. package/dist/standalone-83d5947a.js +0 -2728
  231. package/dist/typescript-0559ee85.js +0 -13660
package/README.md CHANGED
@@ -1,493 +1,493 @@
1
- # Eddyter
2
-
3
- A configurable rich text editor component with AI-powered features and API key authentication.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install eddyter
9
- # or
10
- yarn add eddyter
11
- ```
12
-
13
- ## Features
14
-
15
- - Rich text editor with extensive formatting options
16
- - API key authentication
17
- - Configurable UI components (toolbar, floating menu)
18
- - HTML view option
19
- - Support for tables, images, links, and more
20
- - AI chat integration (for premium plans)
21
- - Environment-based API configuration
22
-
23
- ## Usage
24
-
25
- ### Important: Importing Styles
26
- To ensure proper styling of the editor components including tables, you must import the package's CSS:
27
-
28
- ```jsx
29
- // Import the styles in your application
30
- import 'eddyter/style.css';
31
- ```
32
-
33
- ### Basic Setup
34
-
35
- ```jsx
36
- import React from 'react';
37
- import {
38
- ConfigurableEditorWithAuth,
39
- EditorProvider,
40
- defaultEditorConfig
41
- } from 'eddyter';
42
- // Import required styles
43
- import 'eddyter/style.css';
44
-
45
- function App() {
46
- const apiKey = 'your-api-key'; // Replace with your actual API key
47
-
48
- // Current logged-in user for comments
49
- const currentUser = {
50
- id: 'user-123',
51
- name: 'John Doe',
52
- email: 'john@example.com',
53
- avatar: 'https://example.com/avatar.jpg' // optional
54
- };
55
-
56
- const handleContentChange = (html) => {
57
- console.log('Editor HTML content:', html);
58
- // Handle the HTML content (save to state, send to server, etc.)
59
- };
60
-
61
- return (
62
- <EditorProvider
63
- defaultFontFamilies={defaultEditorConfig.defaultFontFamilies}
64
- currentUser={currentUser}
65
- >
66
- <ConfigurableEditorWithAuth
67
- apiKey={apiKey}
68
- onChange={handleContentChange}
69
- initialContent="<p>Welcome to the editor!</p>"
70
- mentionUserList={["Alice", "Bob", "Charlie"]}
71
- onAuthSuccess={() => console.log('Authentication successful')}
72
- onAuthError={(error) => console.error('Authentication error:', error)}
73
- />
74
- </EditorProvider>
75
- );
76
- }
77
- ```
78
-
79
- ## API Reference
80
-
81
- ### EditorProvider
82
-
83
- Provides authentication and configuration context for the editor.
84
-
85
- #### Props
86
-
87
- - `children`: React nodes to render
88
- - `defaultFontFamilies`: Array of font names (optional)
89
- - `currentUser`: Current logged-in user for comments (optional) - Object with `id`, `name`, `email`, and optional `avatar`
90
- - `enableLinkPreview`: Enable automatic link preview on hover (optional, default: `true`)
91
- - `apiKey`: API key for authentication (optional) - Required only if you need link preview to work immediately without opening the editor first
92
-
93
- ### ConfigurableEditorWithAuth
94
-
95
- The main editor component with authentication.
96
-
97
- #### Props
98
-
99
- - `apiKey`: Your API key for authentication (required)
100
- - `initialContent`: Initial HTML content for the editor (optional) - string
101
- - `onChange`: Callback function when editor content changes (optional) - receives HTML string
102
- - `defaultFontFamilies`: Array of font names for the font selector (optional)
103
- - `mentionUserList`: Array of usernames for mention functionality (optional) - Array of strings like `["Alice", "Bob", "Charlie"]`
104
- - `onAuthSuccess`: Callback function when authentication is successful (optional)
105
- - `onAuthError`: Callback function when authentication fails (optional)
106
- - `customVerifyKey`: Custom function to verify API key (optional)
107
-
108
- ## Examples
109
-
110
- ### Basic Editor with Authentication
111
-
112
- ```jsx
113
- import React from 'react';
114
- import { ConfigurableEditorWithAuth, EditorProvider } from 'eddyter';
115
- import 'eddyter/style.css';
116
-
117
- function App() {
118
- return (
119
- <EditorProvider>
120
- <ConfigurableEditorWithAuth
121
- apiKey="your-api-key"
122
- onAuthSuccess={() => console.log('Authenticated')}
123
- onAuthError={(error) => console.error(error)}
124
- />
125
- </EditorProvider>
126
- );
127
- }
128
- ```
129
-
130
- ### Editor with Content Handling
131
-
132
- ```jsx
133
- import React, { useState } from 'react';
134
- import { ConfigurableEditorWithAuth, EditorProvider } from 'eddyter';
135
- import 'eddyter/style.css';
136
-
137
- function App() {
138
- const [editorContent, setEditorContent] = useState('');
139
-
140
- // Current user (typically from your auth system)
141
- const currentUser = {
142
- id: 'user-456',
143
- name: 'Jane Smith',
144
- email: 'jane@example.com'
145
- };
146
-
147
- const handleContentChange = (html) => {
148
- setEditorContent(html);
149
- console.log('Current content:', html);
150
- // You can also save to localStorage, send to API, etc.
151
- };
152
-
153
- const handleSave = () => {
154
- // Save the HTML content to your backend or localStorage
155
- localStorage.setItem('saved-content', editorContent);
156
- console.log('Content saved!');
157
- };
158
-
159
- const loadSavedContent = () => {
160
- const saved = '<p>Start writing your content here...</p>';
161
- return saved;
162
- };
163
-
164
- return (
165
- <div>
166
- <EditorProvider currentUser={currentUser}>
167
- <ConfigurableEditorWithAuth
168
- apiKey="your-api-key"
169
- initialContent={loadSavedContent()}
170
- onChange={handleContentChange}
171
- defaultFontFamilies={['Arial', 'Helvetica', 'Times New Roman']}
172
- mentionUserList={['Alice', 'Bob', 'Charlie']}
173
- onAuthSuccess={() => console.log('Ready to edit!')}
174
- onAuthError={(error) => console.error('Auth failed:', error)}
175
- />
176
- </EditorProvider>
177
-
178
- <button onClick={handleSave} style={{ marginTop: '10px', padding: '10px' }}>
179
- Save Content
180
- </button>
181
-
182
- <div style={{ marginTop: '20px', padding: '10px', background: '#f5f5f5' }}>
183
- <h3>Current HTML Content:</h3>
184
- <pre>{editorContent}</pre>
185
- </div>
186
- </div>
187
- );
188
- }
189
- ```
190
-
191
- ### Custom API Key Verification
192
-
193
- ```jsx
194
- import React from 'react';
195
- import { ConfigurableEditorWithAuth, EditorProvider } from 'eddyter';
196
- import 'eddyter/style.css';
197
-
198
- function App() {
199
- const customVerifyKey = async (apiKey) => {
200
- try {
201
- const response = await fetch('/api/verify-key', {
202
- method: 'POST',
203
- headers: { 'Content-Type': 'application/json' },
204
- body: JSON.stringify({ apiKey })
205
- });
206
-
207
- const data = await response.json();
208
-
209
- return {
210
- success: data.valid,
211
- message: data.message || 'API key verified'
212
- };
213
- } catch (error) {
214
- return {
215
- success: false,
216
- message: 'Failed to verify API key'
217
- };
218
- }
219
- };
220
-
221
- return (
222
- <EditorProvider>
223
- <ConfigurableEditorWithAuth
224
- apiKey="your-api-key"
225
- customVerifyKey={customVerifyKey}
226
- onChange={(html) => console.log('Content changed:', html)}
227
- />
228
- </EditorProvider>
229
- );
230
- }
231
- ```
232
-
233
- ## Link Preview Feature
234
-
235
- Eddyter includes automatic link preview on hover. When users hover over links in content wrapped by `EditorProvider`, a preview popup shows the link's title, description, and image.
236
-
237
- ### How It Works
238
-
239
- - **Inside the editor**: Link preview works automatically after authentication
240
- - **Outside the editor** (preview mode, saved content): Link preview works if the user has opened the editor at least once in the session (authentication stores the API key)
241
-
242
- ### Preview-Only Scenarios
243
-
244
- If your application displays saved content without ever opening the editor (e.g., a read-only view), you need to pass `apiKey` to `EditorProvider`:
245
-
246
- ```jsx
247
- import React from 'react';
248
- import { EditorProvider } from 'eddyter';
249
- import 'eddyter/style.css';
250
-
251
- function ContentPreviewPage({ savedHtml }) {
252
- return (
253
- <EditorProvider apiKey="your-api-key">
254
- <div dangerouslySetInnerHTML={{ __html: savedHtml }} />
255
- </EditorProvider>
256
- );
257
- }
258
- ```
259
-
260
- ### Disabling Link Preview
261
-
262
- To disable link preview entirely:
263
-
264
- ```jsx
265
- <EditorProvider enableLinkPreview={false}>
266
- {/* Your content */}
267
- </EditorProvider>
268
- ```
269
-
270
- ---
271
-
272
- ## React Native Integration
273
-
274
- You can use Eddyter in React Native applications via WebView by loading a deployed version of the editor.
275
-
276
- ### Prerequisites
277
-
278
- ```bash
279
- npm install react-native-webview
280
- # or
281
- yarn add react-native-webview
282
- ```
283
-
284
- ### RichTextEditor Component
285
-
286
- Create a reusable `RichTextEditor` component that wraps the WebView:
287
-
288
- ```tsx
289
- import React, { useRef, useState, useCallback } from 'react';
290
- import { View, ActivityIndicator, Text, StyleSheet } from 'react-native';
291
- import { WebView, WebViewMessageEvent } from 'react-native-webview';
292
-
293
- interface RichTextEditorProps {
294
- editorBaseUrl: string;
295
- apiKey: string;
296
- initialContent?: string;
297
- theme?: 'light' | 'dark';
298
- style?: object;
299
- onChange?: (content: string) => void;
300
- onReady?: () => void;
301
- onAuthSuccess?: () => void;
302
- onAuthError?: (error: string) => void;
303
- }
304
-
305
- interface WebViewMessage {
306
- type: string;
307
- payload?: Record<string, unknown>;
308
- }
309
-
310
- export const RichTextEditor: React.FC<RichTextEditorProps> = ({
311
- editorBaseUrl,
312
- apiKey,
313
- initialContent,
314
- theme = 'light',
315
- style,
316
- onChange,
317
- onReady,
318
- onAuthSuccess,
319
- onAuthError,
320
- }) => {
321
- const webViewRef = useRef<WebView>(null);
322
- const [isLoading, setIsLoading] = useState(true);
323
- const [error, setError] = useState<string | null>(null);
324
-
325
- const buildEditorUrl = () => {
326
- const baseUrl = editorBaseUrl.replace(/\/$/, '');
327
- const params = new URLSearchParams();
328
- if (apiKey) params.append('apiKey', apiKey);
329
- if (theme) params.append('theme', theme);
330
- return `${baseUrl}?${params.toString()}`;
331
- };
332
-
333
- const handleMessage = useCallback((event: WebViewMessageEvent) => {
334
- try {
335
- const message: WebViewMessage = JSON.parse(event.nativeEvent.data);
336
-
337
- switch (message.type) {
338
- case 'EDITOR_READY':
339
- setIsLoading(false);
340
- onReady?.();
341
- // Send initial content after editor is ready
342
- if (initialContent && webViewRef.current) {
343
- webViewRef.current.postMessage(
344
- JSON.stringify({
345
- type: 'SET_CONTENT',
346
- payload: { content: initialContent },
347
- })
348
- );
349
- }
350
- break;
351
-
352
- case 'CONTENT_CHANGE':
353
- onChange?.(message.payload?.content as string || '');
354
- break;
355
-
356
- case 'AUTH_SUCCESS':
357
- onAuthSuccess?.();
358
- break;
359
-
360
- case 'AUTH_ERROR':
361
- onAuthError?.(message.payload?.error as string);
362
- break;
363
- }
364
- } catch (e) {
365
- console.warn('[RichTextEditor] Failed to parse message:', e);
366
- }
367
- }, [onChange, onReady, onAuthSuccess, onAuthError, initialContent]);
368
-
369
- const handleError = useCallback((syntheticEvent: any) => {
370
- const { nativeEvent } = syntheticEvent;
371
- setError(nativeEvent.description || 'Failed to load editor');
372
- setIsLoading(false);
373
- }, []);
374
-
375
- if (error) {
376
- return (
377
- <View style={styles.errorContainer}>
378
- <Text style={styles.errorText}>Failed to load editor</Text>
379
- <Text style={styles.errorDetail}>{error}</Text>
380
- </View>
381
- );
382
- }
383
-
384
- return (
385
- <View style={[styles.container, style]}>
386
- <WebView
387
- ref={webViewRef}
388
- source={{ uri: buildEditorUrl() }}
389
- style={styles.webview}
390
- onMessage={handleMessage}
391
- onError={handleError}
392
- javaScriptEnabled={true}
393
- domStorageEnabled={true}
394
- startInLoadingState={false}
395
- scalesPageToFit={true}
396
- allowsInlineMediaPlayback={true}
397
- keyboardDisplayRequiresUserAction={false}
398
- />
399
- {isLoading && (
400
- <View style={styles.loadingOverlay}>
401
- <ActivityIndicator size="large" color="#007AFF" />
402
- </View>
403
- )}
404
- </View>
405
- );
406
- };
407
-
408
- const styles = StyleSheet.create({
409
- container: { flex: 1 },
410
- webview: { flex: 1, backgroundColor: 'transparent' },
411
- loadingOverlay: {
412
- ...StyleSheet.absoluteFillObject,
413
- justifyContent: 'center',
414
- alignItems: 'center',
415
- backgroundColor: 'rgba(255, 255, 255, 0.9)',
416
- },
417
- errorContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
418
- errorText: { fontSize: 18, fontWeight: 'bold', color: '#FF3B30' },
419
- errorDetail: { fontSize: 14, color: '#666', marginTop: 8, textAlign: 'center' },
420
- });
421
- ```
422
-
423
- ### Usage Example
424
-
425
- ```tsx
426
- import React, { useState } from 'react';
427
- import { View, KeyboardAvoidingView, Platform } from 'react-native';
428
- import { RichTextEditor } from './components/RichTextEditor';
429
-
430
- const EDITOR_CONFIG = {
431
- editorBaseUrl: 'https://your-deployed-editor-url.com',
432
- apiKey: 'your-api-key',
433
- };
434
-
435
- function NoteEditorScreen() {
436
- const [content, setContent] = useState('');
437
-
438
- return (
439
- <KeyboardAvoidingView
440
- style={{ flex: 1 }}
441
- behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
442
- >
443
- <RichTextEditor
444
- editorBaseUrl={EDITOR_CONFIG.editorBaseUrl}
445
- apiKey={EDITOR_CONFIG.apiKey}
446
- theme="light"
447
- initialContent="<p>Start writing...</p>"
448
- onChange={setContent}
449
- onReady={() => console.log('Editor ready')}
450
- onAuthSuccess={() => console.log('Authenticated')}
451
- onAuthError={(error) => console.error('Auth failed:', error)}
452
- />
453
- </KeyboardAvoidingView>
454
- );
455
- }
456
- ```
457
-
458
- ### Message Protocol
459
-
460
- The editor and React Native communicate via `postMessage`. Here are the supported message types:
461
-
462
- | Message Type | Direction | Description |
463
- |--------------|-----------|-------------|
464
- | `EDITOR_READY` | Editor → RN | Editor has finished loading |
465
- | `CONTENT_CHANGE` | Editor → RN | Content was modified (payload: `{ content: string }`) |
466
- | `AUTH_SUCCESS` | Editor → RN | API key authentication succeeded |
467
- | `AUTH_ERROR` | Editor → RN | Authentication failed (payload: `{ error: string }`) |
468
- | `SET_CONTENT` | RN → Editor | Set editor content (payload: `{ content: string }`) |
469
-
470
- ### Sending Content to Editor
471
-
472
- After receiving the `EDITOR_READY` message, you can programmatically set content:
473
-
474
- ```tsx
475
- webViewRef.current?.postMessage(
476
- JSON.stringify({
477
- type: 'SET_CONTENT',
478
- payload: { content: '<p>New content here</p>' },
479
- })
480
- );
481
- ```
482
-
483
- ---
484
-
485
- ## License
486
-
487
- Eddyter is **proprietary software**.
488
-
489
- - Free for evaluation and non-commercial use
490
- - **Commercial use requires a paid license**
491
- - SaaS, redistribution, and competing products are prohibited without permission
492
-
493
- For commercial licensing, contact: licensing@yourcompany.com
1
+ # Eddyter
2
+
3
+ A configurable rich text editor component with AI-powered features and API key authentication.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install eddyter
9
+ # or
10
+ yarn add eddyter
11
+ ```
12
+
13
+ ## Features
14
+
15
+ - Rich text editor with extensive formatting options
16
+ - API key authentication
17
+ - Configurable UI components (toolbar, floating menu)
18
+ - HTML view option
19
+ - Support for tables, images, links, and more
20
+ - AI chat integration (for premium plans)
21
+ - Environment-based API configuration
22
+
23
+ ## Usage
24
+
25
+ ### Important: Importing Styles
26
+ To ensure proper styling of the editor components including tables, you must import the package's CSS:
27
+
28
+ ```jsx
29
+ // Import the styles in your application
30
+ import 'eddyter/style.css';
31
+ ```
32
+
33
+ ### Basic Setup
34
+
35
+ ```jsx
36
+ import React from 'react';
37
+ import {
38
+ ConfigurableEditorWithAuth,
39
+ EditorProvider,
40
+ defaultEditorConfig
41
+ } from 'eddyter';
42
+ // Import required styles
43
+ import 'eddyter/style.css';
44
+
45
+ function App() {
46
+ const apiKey = 'your-api-key'; // Replace with your actual API key
47
+
48
+ // Current logged-in user for comments
49
+ const currentUser = {
50
+ id: 'user-123',
51
+ name: 'John Doe',
52
+ email: 'john@example.com',
53
+ avatar: 'https://example.com/avatar.jpg' // optional
54
+ };
55
+
56
+ const handleContentChange = (html) => {
57
+ console.log('Editor HTML content:', html);
58
+ // Handle the HTML content (save to state, send to server, etc.)
59
+ };
60
+
61
+ return (
62
+ <EditorProvider
63
+ defaultFontFamilies={defaultEditorConfig.defaultFontFamilies}
64
+ currentUser={currentUser}
65
+ >
66
+ <ConfigurableEditorWithAuth
67
+ apiKey={apiKey}
68
+ onChange={handleContentChange}
69
+ initialContent="<p>Welcome to the editor!</p>"
70
+ mentionUserList={["Alice", "Bob", "Charlie"]}
71
+ onAuthSuccess={() => console.log('Authentication successful')}
72
+ onAuthError={(error) => console.error('Authentication error:', error)}
73
+ />
74
+ </EditorProvider>
75
+ );
76
+ }
77
+ ```
78
+
79
+ ## API Reference
80
+
81
+ ### EditorProvider
82
+
83
+ Provides authentication and configuration context for the editor.
84
+
85
+ #### Props
86
+
87
+ - `children`: React nodes to render
88
+ - `defaultFontFamilies`: Array of font names (optional)
89
+ - `currentUser`: Current logged-in user for comments (optional) - Object with `id`, `name`, `email`, and optional `avatar`
90
+ - `enableLinkPreview`: Enable automatic link preview on hover (optional, default: `true`)
91
+ - `apiKey`: API key for authentication (optional) - Required only if you need link preview to work immediately without opening the editor first
92
+
93
+ ### ConfigurableEditorWithAuth
94
+
95
+ The main editor component with authentication.
96
+
97
+ #### Props
98
+
99
+ - `apiKey`: Your API key for authentication (required)
100
+ - `initialContent`: Initial HTML content for the editor (optional) - string
101
+ - `onChange`: Callback function when editor content changes (optional) - receives HTML string
102
+ - `defaultFontFamilies`: Array of font names for the font selector (optional)
103
+ - `mentionUserList`: Array of usernames for mention functionality (optional) - Array of strings like `["Alice", "Bob", "Charlie"]`
104
+ - `onAuthSuccess`: Callback function when authentication is successful (optional)
105
+ - `onAuthError`: Callback function when authentication fails (optional)
106
+ - `customVerifyKey`: Custom function to verify API key (optional)
107
+
108
+ ## Examples
109
+
110
+ ### Basic Editor with Authentication
111
+
112
+ ```jsx
113
+ import React from 'react';
114
+ import { ConfigurableEditorWithAuth, EditorProvider } from 'eddyter';
115
+ import 'eddyter/style.css';
116
+
117
+ function App() {
118
+ return (
119
+ <EditorProvider>
120
+ <ConfigurableEditorWithAuth
121
+ apiKey="your-api-key"
122
+ onAuthSuccess={() => console.log('Authenticated')}
123
+ onAuthError={(error) => console.error(error)}
124
+ />
125
+ </EditorProvider>
126
+ );
127
+ }
128
+ ```
129
+
130
+ ### Editor with Content Handling
131
+
132
+ ```jsx
133
+ import React, { useState } from 'react';
134
+ import { ConfigurableEditorWithAuth, EditorProvider } from 'eddyter';
135
+ import 'eddyter/style.css';
136
+
137
+ function App() {
138
+ const [editorContent, setEditorContent] = useState('');
139
+
140
+ // Current user (typically from your auth system)
141
+ const currentUser = {
142
+ id: 'user-456',
143
+ name: 'Jane Smith',
144
+ email: 'jane@example.com'
145
+ };
146
+
147
+ const handleContentChange = (html) => {
148
+ setEditorContent(html);
149
+ console.log('Current content:', html);
150
+ // You can also save to localStorage, send to API, etc.
151
+ };
152
+
153
+ const handleSave = () => {
154
+ // Save the HTML content to your backend or localStorage
155
+ localStorage.setItem('saved-content', editorContent);
156
+ console.log('Content saved!');
157
+ };
158
+
159
+ const loadSavedContent = () => {
160
+ const saved = '<p>Start writing your content here...</p>';
161
+ return saved;
162
+ };
163
+
164
+ return (
165
+ <div>
166
+ <EditorProvider currentUser={currentUser}>
167
+ <ConfigurableEditorWithAuth
168
+ apiKey="your-api-key"
169
+ initialContent={loadSavedContent()}
170
+ onChange={handleContentChange}
171
+ defaultFontFamilies={['Arial', 'Helvetica', 'Times New Roman']}
172
+ mentionUserList={['Alice', 'Bob', 'Charlie']}
173
+ onAuthSuccess={() => console.log('Ready to edit!')}
174
+ onAuthError={(error) => console.error('Auth failed:', error)}
175
+ />
176
+ </EditorProvider>
177
+
178
+ <button onClick={handleSave} style={{ marginTop: '10px', padding: '10px' }}>
179
+ Save Content
180
+ </button>
181
+
182
+ <div style={{ marginTop: '20px', padding: '10px', background: '#f5f5f5' }}>
183
+ <h3>Current HTML Content:</h3>
184
+ <pre>{editorContent}</pre>
185
+ </div>
186
+ </div>
187
+ );
188
+ }
189
+ ```
190
+
191
+ ### Custom API Key Verification
192
+
193
+ ```jsx
194
+ import React from 'react';
195
+ import { ConfigurableEditorWithAuth, EditorProvider } from 'eddyter';
196
+ import 'eddyter/style.css';
197
+
198
+ function App() {
199
+ const customVerifyKey = async (apiKey) => {
200
+ try {
201
+ const response = await fetch('/api/verify-key', {
202
+ method: 'POST',
203
+ headers: { 'Content-Type': 'application/json' },
204
+ body: JSON.stringify({ apiKey })
205
+ });
206
+
207
+ const data = await response.json();
208
+
209
+ return {
210
+ success: data.valid,
211
+ message: data.message || 'API key verified'
212
+ };
213
+ } catch (error) {
214
+ return {
215
+ success: false,
216
+ message: 'Failed to verify API key'
217
+ };
218
+ }
219
+ };
220
+
221
+ return (
222
+ <EditorProvider>
223
+ <ConfigurableEditorWithAuth
224
+ apiKey="your-api-key"
225
+ customVerifyKey={customVerifyKey}
226
+ onChange={(html) => console.log('Content changed:', html)}
227
+ />
228
+ </EditorProvider>
229
+ );
230
+ }
231
+ ```
232
+
233
+ ## Link Preview Feature
234
+
235
+ Eddyter includes automatic link preview on hover. When users hover over links in content wrapped by `EditorProvider`, a preview popup shows the link's title, description, and image.
236
+
237
+ ### How It Works
238
+
239
+ - **Inside the editor**: Link preview works automatically after authentication
240
+ - **Outside the editor** (preview mode, saved content): Link preview works if the user has opened the editor at least once in the session (authentication stores the API key)
241
+
242
+ ### Preview-Only Scenarios
243
+
244
+ If your application displays saved content without ever opening the editor (e.g., a read-only view), you need to pass `apiKey` to `EditorProvider`:
245
+
246
+ ```jsx
247
+ import React from 'react';
248
+ import { EditorProvider } from 'eddyter';
249
+ import 'eddyter/style.css';
250
+
251
+ function ContentPreviewPage({ savedHtml }) {
252
+ return (
253
+ <EditorProvider apiKey="your-api-key">
254
+ <div dangerouslySetInnerHTML={{ __html: savedHtml }} />
255
+ </EditorProvider>
256
+ );
257
+ }
258
+ ```
259
+
260
+ ### Disabling Link Preview
261
+
262
+ To disable link preview entirely:
263
+
264
+ ```jsx
265
+ <EditorProvider enableLinkPreview={false}>
266
+ {/* Your content */}
267
+ </EditorProvider>
268
+ ```
269
+
270
+ ---
271
+
272
+ ## React Native Integration
273
+
274
+ You can use Eddyter in React Native applications via WebView by loading a deployed version of the editor.
275
+
276
+ ### Prerequisites
277
+
278
+ ```bash
279
+ npm install react-native-webview
280
+ # or
281
+ yarn add react-native-webview
282
+ ```
283
+
284
+ ### RichTextEditor Component
285
+
286
+ Create a reusable `RichTextEditor` component that wraps the WebView:
287
+
288
+ ```tsx
289
+ import React, { useRef, useState, useCallback } from 'react';
290
+ import { View, ActivityIndicator, Text, StyleSheet } from 'react-native';
291
+ import { WebView, WebViewMessageEvent } from 'react-native-webview';
292
+
293
+ interface RichTextEditorProps {
294
+ editorBaseUrl: string;
295
+ apiKey: string;
296
+ initialContent?: string;
297
+ theme?: 'light' | 'dark';
298
+ style?: object;
299
+ onChange?: (content: string) => void;
300
+ onReady?: () => void;
301
+ onAuthSuccess?: () => void;
302
+ onAuthError?: (error: string) => void;
303
+ }
304
+
305
+ interface WebViewMessage {
306
+ type: string;
307
+ payload?: Record<string, unknown>;
308
+ }
309
+
310
+ export const RichTextEditor: React.FC<RichTextEditorProps> = ({
311
+ editorBaseUrl,
312
+ apiKey,
313
+ initialContent,
314
+ theme = 'light',
315
+ style,
316
+ onChange,
317
+ onReady,
318
+ onAuthSuccess,
319
+ onAuthError,
320
+ }) => {
321
+ const webViewRef = useRef<WebView>(null);
322
+ const [isLoading, setIsLoading] = useState(true);
323
+ const [error, setError] = useState<string | null>(null);
324
+
325
+ const buildEditorUrl = () => {
326
+ const baseUrl = editorBaseUrl.replace(/\/$/, '');
327
+ const params = new URLSearchParams();
328
+ if (apiKey) params.append('apiKey', apiKey);
329
+ if (theme) params.append('theme', theme);
330
+ return `${baseUrl}?${params.toString()}`;
331
+ };
332
+
333
+ const handleMessage = useCallback((event: WebViewMessageEvent) => {
334
+ try {
335
+ const message: WebViewMessage = JSON.parse(event.nativeEvent.data);
336
+
337
+ switch (message.type) {
338
+ case 'EDITOR_READY':
339
+ setIsLoading(false);
340
+ onReady?.();
341
+ // Send initial content after editor is ready
342
+ if (initialContent && webViewRef.current) {
343
+ webViewRef.current.postMessage(
344
+ JSON.stringify({
345
+ type: 'SET_CONTENT',
346
+ payload: { content: initialContent },
347
+ })
348
+ );
349
+ }
350
+ break;
351
+
352
+ case 'CONTENT_CHANGE':
353
+ onChange?.(message.payload?.content as string || '');
354
+ break;
355
+
356
+ case 'AUTH_SUCCESS':
357
+ onAuthSuccess?.();
358
+ break;
359
+
360
+ case 'AUTH_ERROR':
361
+ onAuthError?.(message.payload?.error as string);
362
+ break;
363
+ }
364
+ } catch (e) {
365
+ console.warn('[RichTextEditor] Failed to parse message:', e);
366
+ }
367
+ }, [onChange, onReady, onAuthSuccess, onAuthError, initialContent]);
368
+
369
+ const handleError = useCallback((syntheticEvent: any) => {
370
+ const { nativeEvent } = syntheticEvent;
371
+ setError(nativeEvent.description || 'Failed to load editor');
372
+ setIsLoading(false);
373
+ }, []);
374
+
375
+ if (error) {
376
+ return (
377
+ <View style={styles.errorContainer}>
378
+ <Text style={styles.errorText}>Failed to load editor</Text>
379
+ <Text style={styles.errorDetail}>{error}</Text>
380
+ </View>
381
+ );
382
+ }
383
+
384
+ return (
385
+ <View style={[styles.container, style]}>
386
+ <WebView
387
+ ref={webViewRef}
388
+ source={{ uri: buildEditorUrl() }}
389
+ style={styles.webview}
390
+ onMessage={handleMessage}
391
+ onError={handleError}
392
+ javaScriptEnabled={true}
393
+ domStorageEnabled={true}
394
+ startInLoadingState={false}
395
+ scalesPageToFit={true}
396
+ allowsInlineMediaPlayback={true}
397
+ keyboardDisplayRequiresUserAction={false}
398
+ />
399
+ {isLoading && (
400
+ <View style={styles.loadingOverlay}>
401
+ <ActivityIndicator size="large" color="#007AFF" />
402
+ </View>
403
+ )}
404
+ </View>
405
+ );
406
+ };
407
+
408
+ const styles = StyleSheet.create({
409
+ container: { flex: 1 },
410
+ webview: { flex: 1, backgroundColor: 'transparent' },
411
+ loadingOverlay: {
412
+ ...StyleSheet.absoluteFillObject,
413
+ justifyContent: 'center',
414
+ alignItems: 'center',
415
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
416
+ },
417
+ errorContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
418
+ errorText: { fontSize: 18, fontWeight: 'bold', color: '#FF3B30' },
419
+ errorDetail: { fontSize: 14, color: '#666', marginTop: 8, textAlign: 'center' },
420
+ });
421
+ ```
422
+
423
+ ### Usage Example
424
+
425
+ ```tsx
426
+ import React, { useState } from 'react';
427
+ import { View, KeyboardAvoidingView, Platform } from 'react-native';
428
+ import { RichTextEditor } from './components/RichTextEditor';
429
+
430
+ const EDITOR_CONFIG = {
431
+ editorBaseUrl: 'https://your-deployed-editor-url.com',
432
+ apiKey: 'your-api-key',
433
+ };
434
+
435
+ function NoteEditorScreen() {
436
+ const [content, setContent] = useState('');
437
+
438
+ return (
439
+ <KeyboardAvoidingView
440
+ style={{ flex: 1 }}
441
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
442
+ >
443
+ <RichTextEditor
444
+ editorBaseUrl={EDITOR_CONFIG.editorBaseUrl}
445
+ apiKey={EDITOR_CONFIG.apiKey}
446
+ theme="light"
447
+ initialContent="<p>Start writing...</p>"
448
+ onChange={setContent}
449
+ onReady={() => console.log('Editor ready')}
450
+ onAuthSuccess={() => console.log('Authenticated')}
451
+ onAuthError={(error) => console.error('Auth failed:', error)}
452
+ />
453
+ </KeyboardAvoidingView>
454
+ );
455
+ }
456
+ ```
457
+
458
+ ### Message Protocol
459
+
460
+ The editor and React Native communicate via `postMessage`. Here are the supported message types:
461
+
462
+ | Message Type | Direction | Description |
463
+ |--------------|-----------|-------------|
464
+ | `EDITOR_READY` | Editor → RN | Editor has finished loading |
465
+ | `CONTENT_CHANGE` | Editor → RN | Content was modified (payload: `{ content: string }`) |
466
+ | `AUTH_SUCCESS` | Editor → RN | API key authentication succeeded |
467
+ | `AUTH_ERROR` | Editor → RN | Authentication failed (payload: `{ error: string }`) |
468
+ | `SET_CONTENT` | RN → Editor | Set editor content (payload: `{ content: string }`) |
469
+
470
+ ### Sending Content to Editor
471
+
472
+ After receiving the `EDITOR_READY` message, you can programmatically set content:
473
+
474
+ ```tsx
475
+ webViewRef.current?.postMessage(
476
+ JSON.stringify({
477
+ type: 'SET_CONTENT',
478
+ payload: { content: '<p>New content here</p>' },
479
+ })
480
+ );
481
+ ```
482
+
483
+ ---
484
+
485
+ ## License
486
+
487
+ Eddyter is **proprietary software**.
488
+
489
+ - Free for evaluation and non-commercial use
490
+ - **Commercial use requires a paid license**
491
+ - SaaS, redistribution, and competing products are prohibited without permission
492
+
493
+ For commercial licensing, contact: licensing@yourcompany.com