A fully customizable React rich text editor with no external dependencies. Built from scratch using only React and native browser APIs. Features a comprehensive toolbar similar to popular Markdown editors with file operations, media insertion, and advanced formatting capabilities.
- ✅ No external dependencies - Built entirely with React and native browser APIs
- ✅ Markdown editor-style interface - Comprehensive toolbar with file operations, formatting, and media tools
- ✅ Fully customizable - Enable/disable features via props
- ✅ Modern UI - Clean, responsive design with professional styling
- ✅ TypeScript support - Full TypeScript definitions included
- ✅ Accessible - Keyboard navigation and screen reader support
- ✅ Lightweight - Minimal bundle size
- ✅ File operations - Save, delete, close functionality
- ✅ Media support - Insert links, images, videos, and attachments
- ✅ Advanced formatting - Headings, code blocks, quotes, horizontal rules
- ✅ Color controls - Text and background color options
- ✅ Font controls - Size and family selection
- ✅ Alignment tools - Left, center, right, justify alignment
- ✅ List support - Bullet and numbered lists
- ✅ Preview mode - Real-time content preview
npm install react-quill-editors
import { RichTextEditor } from 'react-quill-editors';
function App() {
const [content, setContent] = useState('');
return (
<RichTextEditor
features={{
// File operations
save: true,
delete: true,
close: true,
// Text formatting
heading: true,
bold: true,
italic: true,
underline: true,
strikethrough: true,
// Font controls
fontSize: true,
fontFamily: true,
// Colors
color: true,
bgColor: true,
// Alignment
align: true,
// Lists
lists: true,
// Media
link: true,
image: true,
video: true,
// Special formatting
code: true,
quote: true,
horizontalRule: true,
// Additional features
attachment: true,
preview: true,
}}
value={content}
onChange={setContent}
onSave={() => console.log('Saving...')}
onDelete={() => console.log('Deleting...')}
onClose={() => console.log('Closing...')}
onPreview={() => console.log('Preview...')}
placeholder="Start typing..."
/>
);
}
Prop | Type | Default | Description |
---|---|---|---|
features |
EditorFeatures |
{} |
Object to enable/disable specific features |
value |
string |
'' |
The HTML content of the editor |
onChange |
(value: string) => void |
- | Callback when content changes |
placeholder |
string |
'Start typing...' |
Placeholder text when editor is empty |
className |
string |
'' |
Additional CSS class name |
style |
React.CSSProperties |
{} |
Inline styles for the editor |
readOnly |
boolean |
false |
Makes the editor read-only |
disabled |
boolean |
false |
Disables the editor completely |
onSave |
() => void |
- | Callback for save button |
onDelete |
() => void |
- | Callback for delete button |
onClose |
() => void |
- | Callback for close button |
onPreview |
() => void |
- | Callback for preview button |
Category | Feature | Prop | Description |
---|---|---|---|
File Operations | |||
Save | save: true |
Save button with callback | |
Delete | delete: true |
Delete button with callback | |
Close | close: true |
Close button with callback | |
Text Formatting | |||
Heading | heading: true |
Insert headings (H1-H6) | |
Bold | bold: true |
Toggle bold text | |
Italic | italic: true |
Toggle italic text | |
Underline | underline: true |
Toggle underlined text | |
Strikethrough | strikethrough: true |
Toggle strikethrough text | |
Font Controls | |||
Font Size | fontSize: true |
Change text size (8px-36px) | |
Font Family | fontFamily: true |
Change font family | |
Colors | |||
Text Color | color: true |
Change text color | |
Background Color | bgColor: true |
Change background color | |
Alignment | |||
Alignment | align: true |
Text alignment (left, center, right, justify) | |
Lists | |||
Lists | lists: true |
Bullet and numbered lists | |
Media | |||
Link | link: true |
Insert links | |
Image | image: true |
Insert images | |
Video | video: true |
Insert videos | |
Special Formatting | |||
Code | code: true |
Insert code blocks | |
Quote | quote: true |
Insert blockquotes | |
Horizontal Rule | horizontalRule: true |
Insert horizontal rules | |
Additional Features | |||
Attachment | attachment: true |
File attachment functionality | |
Preview | preview: true |
Preview mode with callback |
import { RichTextEditor } from 'react-quill-editors';
function BasicEditor() {
const [content, setContent] = useState('');
return (
<RichTextEditor
features={{
bold: true,
italic: true,
underline: true,
}}
value={content}
onChange={setContent}
/>
);
}
import { RichTextEditor } from 'react-quill-editors';
function MarkdownStyleEditor() {
const [content, setContent] = useState('');
const handleSave = () => {
console.log('Saving content:', content);
};
const handleDelete = () => {
if (confirm('Are you sure?')) {
setContent('');
}
};
return (
<RichTextEditor
features={{
// File operations
save: true,
delete: true,
close: true,
// Text formatting
heading: true,
bold: true,
italic: true,
underline: true,
strikethrough: true,
// Font controls
fontSize: true,
fontFamily: true,
// Colors
color: true,
bgColor: true,
// Alignment
align: true,
// Lists
lists: true,
// Media
link: true,
image: true,
video: true,
// Special formatting
code: true,
quote: true,
horizontalRule: true,
// Additional features
attachment: true,
preview: true,
}}
value={content}
onChange={setContent}
onSave={handleSave}
onDelete={handleDelete}
placeholder="Start typing your content..."
/>
);
}
import { RichTextEditor } from 'react-quill-editors';
function ReadOnlyEditor() {
const content = '<p><strong>This is read-only content</strong> with <em>various formatting</em>.</p>';
return (
<RichTextEditor
features={{
bold: true,
italic: true,
underline: true,
fontSize: true,
fontFamily: true,
color: true,
align: true,
}}
value={content}
readOnly={true}
/>
);
}
import { RichTextEditor } from 'react-quill-editors';
function CustomStyledEditor() {
const [content, setContent] = useState('');
return (
<RichTextEditor
features={{
bold: true,
italic: true,
color: true,
align: true,
lists: true,
}}
value={content}
onChange={setContent}
className="custom-editor"
style={{
border: '2px solid #007bff',
borderRadius: '8px',
minHeight: '400px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
}}
/>
);
}
- 8px, 10px, 12px, 14px, 18px, 24px, 36px
- Arial, Times New Roman, Courier New, Georgia, Verdana, Helvetica
The editor includes a comprehensive color palette with 15 predefined colors:
- Basic: Black, White
- Primary: Red, Green, Blue
- Secondary: Yellow, Magenta, Cyan
- Extended: Gray, Maroon, Olive, Purple, Teal, Navy
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Clean build directory
npm run clean
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Akshay Bhalala
- GitHub: @akshaybhalala
- LinkedIn: Akshay Bhalala
- Email: akshay.bhalala@example.com
- Built with React and TypeScript
- Uses native browser
document.execCommand()
API - Inspired by modern Markdown editors and rich text editors
- Special thanks to the React community for inspiration and best practices
- react
- text-editor
- rich-text
- wysiwyg
- editor
- typescript
- markdown
- content-editor
- html-editor
- formatting
- toolbar
- no-dependencies
- lightweight
- customizable
- accessible
- modern-ui
- file-operations
- media-insertion
- color-picker
- font-controls
- alignment-tools
- list-support
- preview-mode