@abduljebar/text-editor 2.2.6 → 2.3.1
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/README.md +372 -372
- package/dist/App.d.ts.map +1 -1
- package/dist/components/StatusBar.d.ts +1 -0
- package/dist/components/StatusBar.d.ts.map +1 -1
- package/dist/components/TextEditor.d.ts +4 -0
- package/dist/components/TextEditor.d.ts.map +1 -1
- package/dist/components/Toolbar.d.ts +2 -0
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/demo.jpg +0 -0
- package/dist/hooks/useTextEditor.d.ts +31 -20
- package/dist/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.js +1382 -1183
- package/dist/index.umd.cjs +61 -20
- package/dist/types/editor.d.ts +18 -0
- package/dist/types/editor.d.ts.map +1 -1
- package/package.json +82 -82
package/README.md
CHANGED
|
@@ -1,373 +1,373 @@
|
|
|
1
|
-
```tsx
|
|
2
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
3
|
-
import { TextEditor } from "@abduljebar/text-editor";
|
|
4
|
-
```
|
|
5
|
-
|
|
6
|
-
# @abduljebar/text-editor
|
|
7
|
-
|
|
8
|
-
A modern, feature-rich React text editor component with beautiful styling and extensive customization options. Perfect for blogs, content management systems, and any application requiring rich text editing capabilities.
|
|
9
|
-
|
|
10
|
-
## ✨ Features
|
|
11
|
-
|
|
12
|
-
### 🎨 Rich Text Editing
|
|
13
|
-
- **Text Formatting**: Bold, italic, underline, strikethrough
|
|
14
|
-
- **Color Support**: 20 text colors & 25 background colors with intuitive pickers
|
|
15
|
-
- **Headings**: H1, H2, H3 with automatic styling
|
|
16
|
-
- **Lists**: Bulleted and numbered lists
|
|
17
|
-
- **Block Elements**: Quotes and code blocks with syntax styling
|
|
18
|
-
- **Undo/Redo**: Full history support
|
|
19
|
-
|
|
20
|
-
### 🎯 Smart UX
|
|
21
|
-
- **Auto-styling**: Automatic application of beautiful Tailwind CSS styles
|
|
22
|
-
- **Contextual Toolbar**: Appears only when focused and editable
|
|
23
|
-
- **Real-time Stats**: Word and character count in status bar
|
|
24
|
-
- **Smart Format Detection**: Visual indicators for active text formats
|
|
25
|
-
- **Tab Support**: Indentation with Tab key
|
|
26
|
-
|
|
27
|
-
### 🔧 Flexible Configuration
|
|
28
|
-
- **Read-only Mode**: Display content without editing capabilities
|
|
29
|
-
- **Customizable Height**: Flexible sizing options
|
|
30
|
-
- **Title Support**: Optional document title with real-time updates
|
|
31
|
-
- **Action Buttons**: Built-in save and export functionality
|
|
32
|
-
- **Event Handling**: Comprehensive callback system
|
|
33
|
-
|
|
34
|
-
### 🚀 Advanced Features
|
|
35
|
-
- **React Hook**: `useTextEditor` for custom implementations
|
|
36
|
-
- **HTML Export**: Generate complete HTML documents
|
|
37
|
-
- **Validation**: Built-in content validation
|
|
38
|
-
- **State Management**: Full control over editor state
|
|
39
|
-
- **TypeScript**: Fully typed for better development experience
|
|
40
|
-
|
|
41
|
-
## 📦 Installation
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
npm install @abduljebar/text-editor
|
|
45
|
-
# or
|
|
46
|
-
yarn add @abduljebar/text-editor
|
|
47
|
-
# or
|
|
48
|
-
pnpm add @abduljebar/text-editor
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## 🚀 Quick Start
|
|
52
|
-
|
|
53
|
-
```tsx
|
|
54
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
55
|
-
import { TextEditor } from "@abduljebar/text-editor";
|
|
56
|
-
|
|
57
|
-
function App() {
|
|
58
|
-
return (
|
|
59
|
-
<TextEditor
|
|
60
|
-
height="min-h-[400px]"
|
|
61
|
-
onChange={(content, html, title) => {
|
|
62
|
-
console.log("Content:", content);
|
|
63
|
-
console.log("HTML:", html);
|
|
64
|
-
console.log("Title:", title);
|
|
65
|
-
}}
|
|
66
|
-
initialContent="<h1>Welcome to Your Document</h1><p>Start editing here...</p>"
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## 📖 Basic Usage
|
|
73
|
-
|
|
74
|
-
### Simple Implementation
|
|
75
|
-
|
|
76
|
-
```tsx
|
|
77
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
78
|
-
import { TextEditor } from "@abduljebar/text-editor";
|
|
79
|
-
|
|
80
|
-
function MyEditor() {
|
|
81
|
-
const handleSave = (content: string, html: string) => {
|
|
82
|
-
// Save to your backend or state management
|
|
83
|
-
console.log("Saving:", { content, html });
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const handleExport = (html: string) => {
|
|
87
|
-
// Export as HTML file
|
|
88
|
-
const blob = new Blob([html], { type: 'text/html' });
|
|
89
|
-
const url = URL.createObjectURL(blob);
|
|
90
|
-
const a = document.createElement('a');
|
|
91
|
-
a.href = url;
|
|
92
|
-
a.download = 'document.html';
|
|
93
|
-
a.click();
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<TextEditor
|
|
98
|
-
showButtons={true}
|
|
99
|
-
showSaveTitle={true}
|
|
100
|
-
showStatusBar={true}
|
|
101
|
-
onSave={handleSave}
|
|
102
|
-
onExport={handleExport}
|
|
103
|
-
onChange={(content, html, title) => {
|
|
104
|
-
// Real-time updates
|
|
105
|
-
console.log("Changes:", { content, html, title });
|
|
106
|
-
}}
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Read-only Mode
|
|
113
|
-
|
|
114
|
-
```tsx
|
|
115
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
116
|
-
import { TextEditor } from "@abduljebar/text-editor";
|
|
117
|
-
|
|
118
|
-
function ReadOnlyView() {
|
|
119
|
-
return (
|
|
120
|
-
<TextEditor
|
|
121
|
-
readOnly={true}
|
|
122
|
-
initialContent="<h1>Published Article</h1><p>This content cannot be edited.</p>"
|
|
123
|
-
showStatusBar={true}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## ⚙️ API Reference
|
|
130
|
-
|
|
131
|
-
### TextEditor Props
|
|
132
|
-
|
|
133
|
-
| Prop | Type | Default | Description |
|
|
134
|
-
|------|------|---------|-------------|
|
|
135
|
-
| `initialContent` | `string` | `""` | Initial HTML content for the editor |
|
|
136
|
-
| `onChange` | `(content: string, html: string, title?: string) => void` | `undefined` | Callback when content changes |
|
|
137
|
-
| `onSave` | `(content: string, html: string) => void` | `undefined` | Callback when save is triggered |
|
|
138
|
-
| `onExport` | `(html: string) => void` | `undefined` | Callback when export is triggered |
|
|
139
|
-
| `readOnly` | `boolean` | `false` | Disable editing when true |
|
|
140
|
-
| `showButtons` | `boolean` | `false` | Show save/export buttons |
|
|
141
|
-
| `showSaveTitle` | `boolean` | `false` | Show document title input |
|
|
142
|
-
| `showStatusBar` | `boolean` | `false` | Show word/character count |
|
|
143
|
-
| `height` | `string` | `"500px"` | Editor height (any CSS value) |
|
|
144
|
-
|
|
145
|
-
### useTextEditor Hook
|
|
146
|
-
|
|
147
|
-
For advanced usage and custom implementations:
|
|
148
|
-
|
|
149
|
-
```tsx
|
|
150
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
151
|
-
import { useTextEditor } from "@abduljebar/text-editor";
|
|
152
|
-
|
|
153
|
-
function CustomEditor() {
|
|
154
|
-
const {
|
|
155
|
-
editorState,
|
|
156
|
-
editorRef,
|
|
157
|
-
updateContent,
|
|
158
|
-
updateTitle,
|
|
159
|
-
executeCommand,
|
|
160
|
-
getValidationResult,
|
|
161
|
-
exportToHTML,
|
|
162
|
-
clearEditor,
|
|
163
|
-
resetToInitial,
|
|
164
|
-
activeFormats,
|
|
165
|
-
isLinkActive,
|
|
166
|
-
} = useTextEditor("Initial content", false);
|
|
167
|
-
|
|
168
|
-
// Use the state and methods to build custom UI
|
|
169
|
-
return (
|
|
170
|
-
<div>
|
|
171
|
-
<div
|
|
172
|
-
ref={editorRef}
|
|
173
|
-
contentEditable
|
|
174
|
-
onInput={(e) => updateContent(e.currentTarget.innerHTML)}
|
|
175
|
-
className="border p-4 min-h-[200px]"
|
|
176
|
-
/>
|
|
177
|
-
<button onClick={() => executeCommand('bold')}>
|
|
178
|
-
Bold
|
|
179
|
-
</button>
|
|
180
|
-
</div>
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
#### Hook Return Values
|
|
186
|
-
|
|
187
|
-
| Property | Type | Description |
|
|
188
|
-
|----------|------|-------------|
|
|
189
|
-
| `editorState` | `object` | Current editor state (content, title, counts) |
|
|
190
|
-
| `editorRef` | `RefObject` | Reference to the editable element |
|
|
191
|
-
| `updateContent` | `(content: string) => void` | Update editor content |
|
|
192
|
-
| `updateTitle` | `(title: string) => void` | Update document title |
|
|
193
|
-
| `executeCommand` | `(command: string, value?: string) => void` | Execute formatting commands |
|
|
194
|
-
| `getValidationResult` | `() => ValidationResult` | Validate and get editor data |
|
|
195
|
-
| `exportToHTML` | `(options?) => string` | Generate HTML export |
|
|
196
|
-
| `clearEditor` | `() => void` | Clear all content |
|
|
197
|
-
| `resetToInitial` | `() => void` | Reset to initial content |
|
|
198
|
-
| `activeFormats` | `object` | Current active text formats |
|
|
199
|
-
| `isLinkActive` | `boolean` | Whether a link is currently selected |
|
|
200
|
-
|
|
201
|
-
## 🎨 Styling & Customization
|
|
202
|
-
|
|
203
|
-
### Default Styling
|
|
204
|
-
|
|
205
|
-
The editor comes with beautiful default styling using Tailwind CSS classes:
|
|
206
|
-
|
|
207
|
-
- **Headings**: Proper hierarchy with borders and spacing
|
|
208
|
-
- **Paragraphs**: Optimal line height and margins
|
|
209
|
-
- **Lists**: Clean indentation and spacing
|
|
210
|
-
- **Code Blocks**: Dark theme with proper monospace fonts
|
|
211
|
-
- **Quotes**: Elegant bordered design
|
|
212
|
-
- **Links**: Blue color with hover effects
|
|
213
|
-
|
|
214
|
-
### Custom Styling
|
|
215
|
-
|
|
216
|
-
You can override the default styles by targeting the editor's CSS classes or using the `className` prop:
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
220
|
-
import { TextEditor } from "@abduljebar/text-editor";
|
|
221
|
-
|
|
222
|
-
<TextEditor
|
|
223
|
-
className="custom-editor-styles"
|
|
224
|
-
// ... other props
|
|
225
|
-
/>
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
```css
|
|
229
|
-
.custom-editor-styles {
|
|
230
|
-
/* Your custom styles */
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.custom-editor-styles h1 {
|
|
234
|
-
/* Custom heading styles */
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
## 🔧 Advanced Examples
|
|
239
|
-
|
|
240
|
-
### Integration with Form Libraries
|
|
241
|
-
|
|
242
|
-
```tsx
|
|
243
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
244
|
-
import { useForm } from 'react-hook-form';
|
|
245
|
-
import { TextEditor } from "@abduljebar/text-editor";
|
|
246
|
-
|
|
247
|
-
function ArticleForm() {
|
|
248
|
-
const { register, handleSubmit, setValue, watch } = useForm();
|
|
249
|
-
|
|
250
|
-
const handleEditorChange = (content: string, html: string, title?: string) => {
|
|
251
|
-
setValue('content', html);
|
|
252
|
-
setValue('title', title);
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
return (
|
|
256
|
-
<form onSubmit={handleSubmit(data => console.log(data))}>
|
|
257
|
-
<TextEditor
|
|
258
|
-
showSaveTitle={true}
|
|
259
|
-
showButtons={true}
|
|
260
|
-
onChange={handleEditorChange}
|
|
261
|
-
onSave={(content, html) => {
|
|
262
|
-
// Handle form submission
|
|
263
|
-
handleSubmit(data => console.log(data))();
|
|
264
|
-
}}
|
|
265
|
-
/>
|
|
266
|
-
</form>
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### Custom Toolbar Implementation
|
|
272
|
-
|
|
273
|
-
```tsx
|
|
274
|
-
import '@abduljebar/text-editor/dist/index.css';
|
|
275
|
-
import { useTextEditor } from "@abduljebar/text-editor";
|
|
276
|
-
|
|
277
|
-
function CustomToolbarEditor() {
|
|
278
|
-
const { executeCommand, activeFormats, editorRef } = useTextEditor();
|
|
279
|
-
|
|
280
|
-
return (
|
|
281
|
-
<div className="editor-container">
|
|
282
|
-
<div className="custom-toolbar">
|
|
283
|
-
<button
|
|
284
|
-
onClick={() => executeCommand('bold')}
|
|
285
|
-
className={activeFormats.bold ? 'active' : ''}
|
|
286
|
-
>
|
|
287
|
-
B
|
|
288
|
-
</button>
|
|
289
|
-
<button
|
|
290
|
-
onClick={() => executeCommand('italic')}
|
|
291
|
-
className={activeFormats.italic ? 'active' : ''}
|
|
292
|
-
>
|
|
293
|
-
I
|
|
294
|
-
</button>
|
|
295
|
-
{/* Add more custom buttons */}
|
|
296
|
-
</div>
|
|
297
|
-
<div
|
|
298
|
-
ref={editorRef}
|
|
299
|
-
contentEditable
|
|
300
|
-
className="editor-content"
|
|
301
|
-
/>
|
|
302
|
-
</div>
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
## 🌈 Color Palettes
|
|
308
|
-
|
|
309
|
-
### Text Colors (20 colors)
|
|
310
|
-
- Basic: Black, White
|
|
311
|
-
- Primary: Red, Green, Blue
|
|
312
|
-
- Secondary: Yellow, Magenta, Cyan, Orange, Purple
|
|
313
|
-
- Additional: Dark Green, Maroon, Teal, Navy, Gray, Brown, Pink, Gold, Light Green, Light Blue
|
|
314
|
-
|
|
315
|
-
### Background Colors (25 colors)
|
|
316
|
-
- Same as text colors plus light variants
|
|
317
|
-
- Light variants: Misty Rose, Honeydew, Alice Blue, Lemon Chiffon, White Smoke, Lavender, and more
|
|
318
|
-
|
|
319
|
-
## 📋 Browser Support
|
|
320
|
-
|
|
321
|
-
- Chrome 60+
|
|
322
|
-
- Firefox 55+
|
|
323
|
-
- Safari 12+
|
|
324
|
-
- Edge 79+
|
|
325
|
-
|
|
326
|
-
## 🔒 Accessibility
|
|
327
|
-
|
|
328
|
-
- Keyboard navigation support
|
|
329
|
-
- ARIA labels for toolbar buttons
|
|
330
|
-
- Focus management
|
|
331
|
-
- Screen reader compatible
|
|
332
|
-
|
|
333
|
-
## 🐛 Troubleshooting
|
|
334
|
-
|
|
335
|
-
### Common Issues
|
|
336
|
-
|
|
337
|
-
1. **Content not updating**: Ensure you're using the `onChange` callback properly
|
|
338
|
-
2. **Styles not applying**: Make sure Tailwind CSS is properly configured in your project
|
|
339
|
-
3. **Toolbar not appearing**: Check that `readOnly` is set to `false` and the editor is focused
|
|
340
|
-
|
|
341
|
-
### Performance Tips
|
|
342
|
-
|
|
343
|
-
- Use `React.memo` if embedding in frequently re-rendering components
|
|
344
|
-
- Debounce `onChange` callbacks for heavy operations
|
|
345
|
-
- Consider using the hook version for complex custom implementations
|
|
346
|
-
|
|
347
|
-
## 🤝 Contributing
|
|
348
|
-
|
|
349
|
-
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
350
|
-
|
|
351
|
-
## 📄 License
|
|
352
|
-
|
|
353
|
-
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
354
|
-
|
|
355
|
-
## 🆘 Support
|
|
356
|
-
|
|
357
|
-
If you encounter any issues or have questions:
|
|
358
|
-
|
|
359
|
-
1. Check the [documentation](#)
|
|
360
|
-
2. Search [existing issues](https://github.com/abduljebar/text-editor/issues)
|
|
361
|
-
3. Create a [new issue](https://github.com/abduljebar/text-editor/issues/new)
|
|
362
|
-
|
|
363
|
-
## 🚀 Changelog
|
|
364
|
-
|
|
365
|
-
### v1.0.0
|
|
366
|
-
- Initial release with core editing features
|
|
367
|
-
- Comprehensive text formatting options
|
|
368
|
-
- Color support and styling system
|
|
369
|
-
- React hook for advanced usage
|
|
370
|
-
|
|
371
|
-
---
|
|
372
|
-
|
|
1
|
+
```tsx
|
|
2
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
3
|
+
import { TextEditor } from "@abduljebar/text-editor";
|
|
4
|
+
```
|
|
5
|
+
|
|
6
|
+
# @abduljebar/text-editor
|
|
7
|
+
|
|
8
|
+
A modern, feature-rich React text editor component with beautiful styling and extensive customization options. Perfect for blogs, content management systems, and any application requiring rich text editing capabilities.
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
### 🎨 Rich Text Editing
|
|
13
|
+
- **Text Formatting**: Bold, italic, underline, strikethrough
|
|
14
|
+
- **Color Support**: 20 text colors & 25 background colors with intuitive pickers
|
|
15
|
+
- **Headings**: H1, H2, H3 with automatic styling
|
|
16
|
+
- **Lists**: Bulleted and numbered lists
|
|
17
|
+
- **Block Elements**: Quotes and code blocks with syntax styling
|
|
18
|
+
- **Undo/Redo**: Full history support
|
|
19
|
+
|
|
20
|
+
### 🎯 Smart UX
|
|
21
|
+
- **Auto-styling**: Automatic application of beautiful Tailwind CSS styles
|
|
22
|
+
- **Contextual Toolbar**: Appears only when focused and editable
|
|
23
|
+
- **Real-time Stats**: Word and character count in status bar
|
|
24
|
+
- **Smart Format Detection**: Visual indicators for active text formats
|
|
25
|
+
- **Tab Support**: Indentation with Tab key
|
|
26
|
+
|
|
27
|
+
### 🔧 Flexible Configuration
|
|
28
|
+
- **Read-only Mode**: Display content without editing capabilities
|
|
29
|
+
- **Customizable Height**: Flexible sizing options
|
|
30
|
+
- **Title Support**: Optional document title with real-time updates
|
|
31
|
+
- **Action Buttons**: Built-in save and export functionality
|
|
32
|
+
- **Event Handling**: Comprehensive callback system
|
|
33
|
+
|
|
34
|
+
### 🚀 Advanced Features
|
|
35
|
+
- **React Hook**: `useTextEditor` for custom implementations
|
|
36
|
+
- **HTML Export**: Generate complete HTML documents
|
|
37
|
+
- **Validation**: Built-in content validation
|
|
38
|
+
- **State Management**: Full control over editor state
|
|
39
|
+
- **TypeScript**: Fully typed for better development experience
|
|
40
|
+
|
|
41
|
+
## 📦 Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @abduljebar/text-editor
|
|
45
|
+
# or
|
|
46
|
+
yarn add @abduljebar/text-editor
|
|
47
|
+
# or
|
|
48
|
+
pnpm add @abduljebar/text-editor
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 🚀 Quick Start
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
55
|
+
import { TextEditor } from "@abduljebar/text-editor";
|
|
56
|
+
|
|
57
|
+
function App() {
|
|
58
|
+
return (
|
|
59
|
+
<TextEditor
|
|
60
|
+
height="min-h-[400px]"
|
|
61
|
+
onChange={(content, html, title) => {
|
|
62
|
+
console.log("Content:", content);
|
|
63
|
+
console.log("HTML:", html);
|
|
64
|
+
console.log("Title:", title);
|
|
65
|
+
}}
|
|
66
|
+
initialContent="<h1>Welcome to Your Document</h1><p>Start editing here...</p>"
|
|
67
|
+
/>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 📖 Basic Usage
|
|
73
|
+
|
|
74
|
+
### Simple Implementation
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
78
|
+
import { TextEditor } from "@abduljebar/text-editor";
|
|
79
|
+
|
|
80
|
+
function MyEditor() {
|
|
81
|
+
const handleSave = (content: string, html: string) => {
|
|
82
|
+
// Save to your backend or state management
|
|
83
|
+
console.log("Saving:", { content, html });
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const handleExport = (html: string) => {
|
|
87
|
+
// Export as HTML file
|
|
88
|
+
const blob = new Blob([html], { type: 'text/html' });
|
|
89
|
+
const url = URL.createObjectURL(blob);
|
|
90
|
+
const a = document.createElement('a');
|
|
91
|
+
a.href = url;
|
|
92
|
+
a.download = 'document.html';
|
|
93
|
+
a.click();
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<TextEditor
|
|
98
|
+
showButtons={true}
|
|
99
|
+
showSaveTitle={true}
|
|
100
|
+
showStatusBar={true}
|
|
101
|
+
onSave={handleSave}
|
|
102
|
+
onExport={handleExport}
|
|
103
|
+
onChange={(content, html, title) => {
|
|
104
|
+
// Real-time updates
|
|
105
|
+
console.log("Changes:", { content, html, title });
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Read-only Mode
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
116
|
+
import { TextEditor } from "@abduljebar/text-editor";
|
|
117
|
+
|
|
118
|
+
function ReadOnlyView() {
|
|
119
|
+
return (
|
|
120
|
+
<TextEditor
|
|
121
|
+
readOnly={true}
|
|
122
|
+
initialContent="<h1>Published Article</h1><p>This content cannot be edited.</p>"
|
|
123
|
+
showStatusBar={true}
|
|
124
|
+
/>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## ⚙️ API Reference
|
|
130
|
+
|
|
131
|
+
### TextEditor Props
|
|
132
|
+
|
|
133
|
+
| Prop | Type | Default | Description |
|
|
134
|
+
|------|------|---------|-------------|
|
|
135
|
+
| `initialContent` | `string` | `""` | Initial HTML content for the editor |
|
|
136
|
+
| `onChange` | `(content: string, html: string, title?: string) => void` | `undefined` | Callback when content changes |
|
|
137
|
+
| `onSave` | `(content: string, html: string) => void` | `undefined` | Callback when save is triggered |
|
|
138
|
+
| `onExport` | `(html: string) => void` | `undefined` | Callback when export is triggered |
|
|
139
|
+
| `readOnly` | `boolean` | `false` | Disable editing when true |
|
|
140
|
+
| `showButtons` | `boolean` | `false` | Show save/export buttons |
|
|
141
|
+
| `showSaveTitle` | `boolean` | `false` | Show document title input |
|
|
142
|
+
| `showStatusBar` | `boolean` | `false` | Show word/character count |
|
|
143
|
+
| `height` | `string` | `"500px"` | Editor height (any CSS value) |
|
|
144
|
+
|
|
145
|
+
### useTextEditor Hook
|
|
146
|
+
|
|
147
|
+
For advanced usage and custom implementations:
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
151
|
+
import { useTextEditor } from "@abduljebar/text-editor";
|
|
152
|
+
|
|
153
|
+
function CustomEditor() {
|
|
154
|
+
const {
|
|
155
|
+
editorState,
|
|
156
|
+
editorRef,
|
|
157
|
+
updateContent,
|
|
158
|
+
updateTitle,
|
|
159
|
+
executeCommand,
|
|
160
|
+
getValidationResult,
|
|
161
|
+
exportToHTML,
|
|
162
|
+
clearEditor,
|
|
163
|
+
resetToInitial,
|
|
164
|
+
activeFormats,
|
|
165
|
+
isLinkActive,
|
|
166
|
+
} = useTextEditor("Initial content", false);
|
|
167
|
+
|
|
168
|
+
// Use the state and methods to build custom UI
|
|
169
|
+
return (
|
|
170
|
+
<div>
|
|
171
|
+
<div
|
|
172
|
+
ref={editorRef}
|
|
173
|
+
contentEditable
|
|
174
|
+
onInput={(e) => updateContent(e.currentTarget.innerHTML)}
|
|
175
|
+
className="border p-4 min-h-[200px]"
|
|
176
|
+
/>
|
|
177
|
+
<button onClick={() => executeCommand('bold')}>
|
|
178
|
+
Bold
|
|
179
|
+
</button>
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### Hook Return Values
|
|
186
|
+
|
|
187
|
+
| Property | Type | Description |
|
|
188
|
+
|----------|------|-------------|
|
|
189
|
+
| `editorState` | `object` | Current editor state (content, title, counts) |
|
|
190
|
+
| `editorRef` | `RefObject` | Reference to the editable element |
|
|
191
|
+
| `updateContent` | `(content: string) => void` | Update editor content |
|
|
192
|
+
| `updateTitle` | `(title: string) => void` | Update document title |
|
|
193
|
+
| `executeCommand` | `(command: string, value?: string) => void` | Execute formatting commands |
|
|
194
|
+
| `getValidationResult` | `() => ValidationResult` | Validate and get editor data |
|
|
195
|
+
| `exportToHTML` | `(options?) => string` | Generate HTML export |
|
|
196
|
+
| `clearEditor` | `() => void` | Clear all content |
|
|
197
|
+
| `resetToInitial` | `() => void` | Reset to initial content |
|
|
198
|
+
| `activeFormats` | `object` | Current active text formats |
|
|
199
|
+
| `isLinkActive` | `boolean` | Whether a link is currently selected |
|
|
200
|
+
|
|
201
|
+
## 🎨 Styling & Customization
|
|
202
|
+
|
|
203
|
+
### Default Styling
|
|
204
|
+
|
|
205
|
+
The editor comes with beautiful default styling using Tailwind CSS classes:
|
|
206
|
+
|
|
207
|
+
- **Headings**: Proper hierarchy with borders and spacing
|
|
208
|
+
- **Paragraphs**: Optimal line height and margins
|
|
209
|
+
- **Lists**: Clean indentation and spacing
|
|
210
|
+
- **Code Blocks**: Dark theme with proper monospace fonts
|
|
211
|
+
- **Quotes**: Elegant bordered design
|
|
212
|
+
- **Links**: Blue color with hover effects
|
|
213
|
+
|
|
214
|
+
### Custom Styling
|
|
215
|
+
|
|
216
|
+
You can override the default styles by targeting the editor's CSS classes or using the `className` prop:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
220
|
+
import { TextEditor } from "@abduljebar/text-editor";
|
|
221
|
+
|
|
222
|
+
<TextEditor
|
|
223
|
+
className="custom-editor-styles"
|
|
224
|
+
// ... other props
|
|
225
|
+
/>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```css
|
|
229
|
+
.custom-editor-styles {
|
|
230
|
+
/* Your custom styles */
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.custom-editor-styles h1 {
|
|
234
|
+
/* Custom heading styles */
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 🔧 Advanced Examples
|
|
239
|
+
|
|
240
|
+
### Integration with Form Libraries
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
244
|
+
import { useForm } from 'react-hook-form';
|
|
245
|
+
import { TextEditor } from "@abduljebar/text-editor";
|
|
246
|
+
|
|
247
|
+
function ArticleForm() {
|
|
248
|
+
const { register, handleSubmit, setValue, watch } = useForm();
|
|
249
|
+
|
|
250
|
+
const handleEditorChange = (content: string, html: string, title?: string) => {
|
|
251
|
+
setValue('content', html);
|
|
252
|
+
setValue('title', title);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
return (
|
|
256
|
+
<form onSubmit={handleSubmit(data => console.log(data))}>
|
|
257
|
+
<TextEditor
|
|
258
|
+
showSaveTitle={true}
|
|
259
|
+
showButtons={true}
|
|
260
|
+
onChange={handleEditorChange}
|
|
261
|
+
onSave={(content, html) => {
|
|
262
|
+
// Handle form submission
|
|
263
|
+
handleSubmit(data => console.log(data))();
|
|
264
|
+
}}
|
|
265
|
+
/>
|
|
266
|
+
</form>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Custom Toolbar Implementation
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
import '@abduljebar/text-editor/dist/index.css';
|
|
275
|
+
import { useTextEditor } from "@abduljebar/text-editor";
|
|
276
|
+
|
|
277
|
+
function CustomToolbarEditor() {
|
|
278
|
+
const { executeCommand, activeFormats, editorRef } = useTextEditor();
|
|
279
|
+
|
|
280
|
+
return (
|
|
281
|
+
<div className="editor-container">
|
|
282
|
+
<div className="custom-toolbar">
|
|
283
|
+
<button
|
|
284
|
+
onClick={() => executeCommand('bold')}
|
|
285
|
+
className={activeFormats.bold ? 'active' : ''}
|
|
286
|
+
>
|
|
287
|
+
B
|
|
288
|
+
</button>
|
|
289
|
+
<button
|
|
290
|
+
onClick={() => executeCommand('italic')}
|
|
291
|
+
className={activeFormats.italic ? 'active' : ''}
|
|
292
|
+
>
|
|
293
|
+
I
|
|
294
|
+
</button>
|
|
295
|
+
{/* Add more custom buttons */}
|
|
296
|
+
</div>
|
|
297
|
+
<div
|
|
298
|
+
ref={editorRef}
|
|
299
|
+
contentEditable
|
|
300
|
+
className="editor-content"
|
|
301
|
+
/>
|
|
302
|
+
</div>
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## 🌈 Color Palettes
|
|
308
|
+
|
|
309
|
+
### Text Colors (20 colors)
|
|
310
|
+
- Basic: Black, White
|
|
311
|
+
- Primary: Red, Green, Blue
|
|
312
|
+
- Secondary: Yellow, Magenta, Cyan, Orange, Purple
|
|
313
|
+
- Additional: Dark Green, Maroon, Teal, Navy, Gray, Brown, Pink, Gold, Light Green, Light Blue
|
|
314
|
+
|
|
315
|
+
### Background Colors (25 colors)
|
|
316
|
+
- Same as text colors plus light variants
|
|
317
|
+
- Light variants: Misty Rose, Honeydew, Alice Blue, Lemon Chiffon, White Smoke, Lavender, and more
|
|
318
|
+
|
|
319
|
+
## 📋 Browser Support
|
|
320
|
+
|
|
321
|
+
- Chrome 60+
|
|
322
|
+
- Firefox 55+
|
|
323
|
+
- Safari 12+
|
|
324
|
+
- Edge 79+
|
|
325
|
+
|
|
326
|
+
## 🔒 Accessibility
|
|
327
|
+
|
|
328
|
+
- Keyboard navigation support
|
|
329
|
+
- ARIA labels for toolbar buttons
|
|
330
|
+
- Focus management
|
|
331
|
+
- Screen reader compatible
|
|
332
|
+
|
|
333
|
+
## 🐛 Troubleshooting
|
|
334
|
+
|
|
335
|
+
### Common Issues
|
|
336
|
+
|
|
337
|
+
1. **Content not updating**: Ensure you're using the `onChange` callback properly
|
|
338
|
+
2. **Styles not applying**: Make sure Tailwind CSS is properly configured in your project
|
|
339
|
+
3. **Toolbar not appearing**: Check that `readOnly` is set to `false` and the editor is focused
|
|
340
|
+
|
|
341
|
+
### Performance Tips
|
|
342
|
+
|
|
343
|
+
- Use `React.memo` if embedding in frequently re-rendering components
|
|
344
|
+
- Debounce `onChange` callbacks for heavy operations
|
|
345
|
+
- Consider using the hook version for complex custom implementations
|
|
346
|
+
|
|
347
|
+
## 🤝 Contributing
|
|
348
|
+
|
|
349
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
350
|
+
|
|
351
|
+
## 📄 License
|
|
352
|
+
|
|
353
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
354
|
+
|
|
355
|
+
## 🆘 Support
|
|
356
|
+
|
|
357
|
+
If you encounter any issues or have questions:
|
|
358
|
+
|
|
359
|
+
1. Check the [documentation](#)
|
|
360
|
+
2. Search [existing issues](https://github.com/abduljebar/text-editor/issues)
|
|
361
|
+
3. Create a [new issue](https://github.com/abduljebar/text-editor/issues/new)
|
|
362
|
+
|
|
363
|
+
## 🚀 Changelog
|
|
364
|
+
|
|
365
|
+
### v1.0.0
|
|
366
|
+
- Initial release with core editing features
|
|
367
|
+
- Comprehensive text formatting options
|
|
368
|
+
- Color support and styling system
|
|
369
|
+
- React hook for advanced usage
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
373
|
Built with ❤️ by [AbdulJebar Sani](https://github.com/abduljebar49)
|