editium
Version:
A powerful and feature-rich React rich text editor component built with Slate.js, featuring comprehensive formatting options, tables, images, find & replace, and more
428 lines (317 loc) • 11.2 kB
Markdown
<div align="center">
# Editium
[](https://www.npmjs.com/package/editium)
[](https://opensource.org/licenses/MIT)
[](https://bundlephobia.com/package/editium)
[](https://www.typescriptlang.org/)
**Production-ready rich text editor for React and Vanilla JavaScript**
Modern • Lightweight • Customizable • Zero Dependencies (Vanilla)
[Quick Start](#quick-start) • [Documentation](#documentation) • [Examples](#examples) • [API Reference](#api-reference)
</div>
---
## Overview
Editium is a flexible rich text editor that works seamlessly in both **React** and **Vanilla JavaScript** environments. Built for developers who need a reliable, feature-rich editor without the complexity.
**Why Editium?**
- **Dual-Mode Support**: Same powerful features in React (Slate.js) and Vanilla JS (pure JavaScript)
- **Production Ready**: Battle-tested with comprehensive formatting tools and advanced features
- **Developer Experience**: Get from npm install to working editor in under 60 seconds
- **Export Flexibility**: HTML, JSON, and plain text output formats
- **Fully Customizable**: Configure exactly what you need, hide what you don't
---
## Quick Start
### React
```bash
npm install editium
```
```tsx
import { Editium } from 'editium';
function App() {
return <Editium placeholder="Start typing..." toolbar="all" />;
}
```
**[See live demo →](https://editium.vercel.app/)**
### Vanilla JavaScript
**Single file - no build step required:**
```html
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/editium/vanilla/editium.bundle.js"></script>
</head>
<body>
<div id="editor"></div>
<script>
const editor = new Editium({
container: document.getElementById('editor'),
placeholder: 'Start typing...',
toolbar: 'all'
});
</script>
</body>
</html>
```
**[See live demo →](https://codepen.io/nabarup-duplicate/pen/WbrKdpj)**
---
## Key Features
**Rich Text Editing**
- Comprehensive formatting: bold, italic, underline, strikethrough, code
- 8 heading levels, blockquotes, and code blocks
- Text and background colors
- Superscript and subscript
**Advanced Capabilities**
- Full table support with dynamic rows/columns
- Resizable images with custom upload handlers
- Bulleted and numbered lists with nesting
- Find and replace with match highlighting
- Text alignment (left, center, right, justify)
**Developer Experience**
- TypeScript support with full type definitions
- HTML and JSON export formats
- Customizable toolbar (show only what you need)
- Keyboard shortcuts for efficient editing
- Read-only mode for content display
- Word and character counting
- Fullscreen editing mode
**Framework Flexibility**
- **React**: Component-based with hooks support
- **Vanilla JS**: Zero dependencies, works anywhere
- Same API and features across both versions
---
## Installation
```bash
npm install editium
```
**Peer dependencies (React only):**
```bash
npm install react react-dom
```
**CDN (Vanilla JS):**
```html
<script src="https://unpkg.com/editium/vanilla/editium.bundle.js"></script>
```
---
## Documentation
### React Usage
**Basic Example**
```tsx
import { Editium } from 'editium';
function App() {
return <Editium toolbar="all" placeholder="Start typing..." />;
}
```
**With Content Management**
```tsx
import React, { useState } from 'react';
import { Editium } from 'editium';
function Editor() {
const [content, setContent] = useState({ html: '', json: [] });
return (
<Editium
toolbar="all"
onChange={(html, json) => setContent({ html, json })}
showWordCount={true}
/>
);
}
```
**Custom Toolbar**
```tsx
<Editium
toolbar={[
'bold', 'italic', 'underline',
'separator',
'heading-one', 'heading-two',
'separator',
'bulleted-list', 'numbered-list',
'link', 'image'
]}
/>
```
**[→ Full React Documentation](./react/README.md)**
### Vanilla JavaScript Usage
**CDN (Recommended)**
```html
<script src="https://unpkg.com/editium/vanilla/editium.bundle.js"></script>
<div id="editor"></div>
<script>
const editor = new Editium({
container: document.getElementById('editor'),
toolbar: 'all',
placeholder: 'Start typing...'
});
// Get content
const html = editor.getHTML();
const json = editor.getJSON();
</script>
```
**NPM**
```javascript
import 'editium/vanilla/editium.css';
import Editium from 'editium/vanilla/editium.js';
const editor = new Editium({
container: document.getElementById('editor'),
toolbar: 'all'
});
```
**[→ Full Vanilla JS Documentation](./vanilla/README.md)**
---
## API Reference
### React Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `toolbar` | `ToolbarItem[] \| 'all'` | Basic items | Toolbar configuration |
| `placeholder` | `string` | `'Start typing...'` | Placeholder text |
| `onChange` | `(html, json) => void` | - | Content change callback |
| `initialValue` | `string \| CustomElement[]` | - | Initial content |
| `readOnly` | `boolean` | `false` | Read-only mode |
| `showWordCount` | `boolean` | `false` | Show word/character count |
| `height` | `string \| number` | `'200px'` | Editor height |
| `onImageUpload` | `(file: File) => Promise<string>` | - | Custom image upload |
### Vanilla JS Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `container` | `HTMLElement` | required | DOM element for editor |
| `toolbar` | `string \| array` | `'all'` | Toolbar configuration |
| `placeholder` | `string` | `''` | Placeholder text |
| `onChange` | `function` | - | Content change callback |
| `readOnly` | `boolean` | `false` | Read-only mode |
| `showWordCount` | `boolean` | `false` | Show word/character count |
| `height` | `string \| number` | `'200px'` | Editor height |
| `onImageUpload` | `function` | - | Custom image upload |
### Vanilla JS Methods
```javascript
editor.getHTML() // Returns HTML string
editor.getText() // Returns plain text
editor.getJSON() // Returns JSON structure
editor.setContent(html) // Set editor content
editor.clear() // Clear editor
editor.focus() // Focus editor
editor.destroy() // Cleanup editor
```
### Toolbar Items
Available items: `bold`, `italic`, `underline`, `strikethrough`, `code`, `superscript`, `subscript`, `heading-one` through `heading-eight`, `paragraph`, `blockquote`, `code-block`, `bulleted-list`, `numbered-list`, `indent`, `outdent`, `left`, `center`, `right`, `justify`, `text-color`, `bg-color`, `link`, `image`, `table`, `horizontal-rule`, `undo`, `redo`, `find-replace`, `fullscreen`, `view-output`, `separator`
---
## Examples
### Custom Image Upload
**React:**
```tsx
const handleImageUpload = async (file: File) => {
const formData = new FormData();
formData.append('image', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const { url } = await response.json();
return url;
};
<Editium onImageUpload={handleImageUpload} />
```
**Vanilla JS:**
```javascript
const editor = new Editium({
container: document.getElementById('editor'),
onImageUpload: async (file) => {
const formData = new FormData();
formData.append('image', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const { url } = await response.json();
return url;
}
});
```
### Saving Content
**React:**
```tsx
function EditorWithSave() {
const [content, setContent] = useState({ html: '', json: [] });
const handleSave = async () => {
await fetch('/api/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(content)
});
};
return (
<>
<Editium onChange={(html, json) => setContent({ html, json })} />
<button onClick={handleSave}>Save</button>
</>
);
}
```
**Vanilla JS:**
```javascript
const editor = new Editium({
container: document.getElementById('editor'),
onChange: (content) => {
localStorage.setItem('content', JSON.stringify({
html: content.html,
json: content.json
}));
}
});
```
### Height Configuration
```tsx
// React
<Editium height={400} minHeight={200} maxHeight={600} />
// Vanilla JS
new Editium({
container: document.getElementById('editor'),
height: '400px',
minHeight: '200px',
maxHeight: '600px'
});
```
---
## Keyboard Shortcuts
| Shortcut | Action |
|----------|--------|
| `Ctrl/Cmd + B` | Bold |
| `Ctrl/Cmd + I` | Italic |
| `Ctrl/Cmd + U` | Underline |
| `Ctrl/Cmd + Z` | Undo |
| `Ctrl/Cmd + Y` | Redo |
| `Ctrl/Cmd + K` | Insert link |
| `F11` | Fullscreen |
| `Tab` | Indent list |
| `Shift + Tab` | Outdent list |
---
## Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
---
## Community & Support
**Get Help**
- [GitHub Issues](https://github.com/NabarupDev/Editium/issues) - Bug reports and feature requests
- [GitHub Discussions](https://github.com/NabarupDev/Editium/discussions) - Questions and community support
- Security: See `SECURITY.md` for responsible disclosure and contact instructions
**Contributing**
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
**Code of Conduct**
This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
---
## License
MIT License - See [LICENSE](LICENSE) file for details.
Copyright © 2025 [Nabarup Dev](https://github.com/NabarupDev)
---
## Acknowledgments
- Built with [Slate.js](https://www.slatejs.org/) for the React version
- Inspired by modern rich text editors: TipTap, ProseMirror, and Quill
---
<div align="center">
**Made with ❤️ by [Nabarup Dev](https://github.com/NabarupDev)**
⭐ **Star us on [GitHub](https://github.com/NabarupDev/Editium)** if you find this project useful!
[NPM](https://www.npmjs.com/package/editium) • [GitHub](https://github.com/NabarupDev/Editium) • [Issues](https://github.com/NabarupDev/Editium/issues)
</div>