Package Exports
- smartrte-react
- smartrte-react/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (smartrte-react) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Smart RTE (Rich Text Editor) - React
A powerful, feature-rich Rich Text Editor built for React applications with support for tables, formulas (LaTeX/KaTeX), media management, and advanced text formatting.
๐ Features
- ๐ Rich Text Editing: Full-featured WYSIWYG editor with all standard formatting options
- ๐ Advanced Table Support: Create, edit, merge, split cells, and customize tables
- ๐ข Mathematical Formulas: LaTeX/KaTeX integration for rendering mathematical expressions
- ๐ผ๏ธ Media Management: Image upload, resize, drag-and-drop, and custom media manager integration
- ๐จ Styling Options: Font sizes (8-96pt), text colors, background colors, and more
- ๐ Link Management: Easy insertion and editing of hyperlinks
- ๐ฑ Responsive: Works seamlessly across different screen sizes
- โก Lightweight: Minimal dependencies, optimized for performance
- ๐ฏ TypeScript Support: Fully typed for better developer experience
- ๐ง Customizable: Toggle features on/off, custom media managers, and more
๐ฆ Installation
Using npm
npm install smartrte-reactUsing yarn
yarn add smartrte-reactUsing pnpm
pnpm add smartrte-react๐ Quick Start
๐ฎ Live Demo
Try the editor instantly in your browser:
- Live Demo (Deployed Version)
- CodeSandbox Playground (Interactive)
Basic Usage
import React, { useState } from 'react';
import { ClassicEditor } from 'smartrte-react';
function App() {
const [content, setContent] = useState('<p>Start typing...</p>');
return (
<div>
<ClassicEditor
value={content}
onChange={(html) => setContent(html)}
placeholder="Type hereโฆ"
/>
</div>
);
}
export default App;๐ Documentation
Component API
ClassicEditor Props
| Prop | Type | Default | Description |
|---|---|---|---|
value |
string |
undefined |
HTML content of the editor |
onChange |
(html: string) => void |
undefined |
Callback fired when content changes |
placeholder |
string |
"Type hereโฆ" |
Placeholder text when editor is empty |
minHeight |
number | string |
200 |
Minimum height of the editor (in pixels) |
maxHeight |
number | string |
500 |
Maximum height of the editor (in pixels) |
readOnly |
boolean |
false |
Make the editor read-only |
table |
boolean |
true |
Enable/disable table functionality |
media |
boolean |
true |
Enable/disable media/image functionality |
formula |
boolean |
true |
Enable/disable formula/LaTeX functionality |
mediaManager |
MediaManagerAdapter |
undefined |
Custom media manager for handling images |
fonts |
{ name: string; value: string }[] |
Default web-safe fonts | Custom font list for the toolbar |
defaultFont |
string |
undefined |
Default font family for the editor content |
theme |
"light" | "dark" |
"light" |
Built-in theme mode |
className |
string |
undefined |
Custom CSS class for theming via CSS variable overrides |
Advanced Examples
Complete Example with All Features
import React, { useState } from 'react';
import { ClassicEditor, MediaManagerAdapter } from 'smartrte-react';
// Custom media manager implementation
const customMediaManager: MediaManagerAdapter = {
async search(query) {
// Implement your media search logic
const response = await fetch(`/api/media/search?q=${query.text}`);
const data = await response.json();
return {
items: data.items.map(item => ({
id: item.id,
url: item.url,
thumbnailUrl: item.thumbnailUrl,
title: item.title,
})),
};
},
async upload(file) {
// Implement your file upload logic
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/media/upload', {
method: 'POST',
body: formData,
});
const data = await response.json();
return {
id: data.id,
url: data.url,
thumbnailUrl: data.thumbnailUrl,
title: data.title,
};
},
};
function AdvancedEditor() {
const [content, setContent] = useState('');
return (
<ClassicEditor
value={content}
onChange={(html) => {
console.log('Content changed:', html);
setContent(html);
}}
placeholder="Start editing..."
minHeight={300}
maxHeight={800}
table={true}
media={true}
formula={true}
mediaManager={customMediaManager}
/>
);
}
export default AdvancedEditor;Read-Only Mode
import { ClassicEditor } from 'smartrte-react';
function ReadOnlyEditor({ content }) {
return (
<ClassicEditor
value={content}
readOnly={true}
minHeight={200}
/>
);
}Minimal Editor (No Tables, Media, or Formulas)
import { ClassicEditor } from 'smartrte-react';
function MinimalEditor() {
const [content, setContent] = useState('');
return (
<ClassicEditor
value={content}
onChange={setContent}
table={false}
media={false}
formula={false}
placeholder="Simple text editor"
/>
);
}Next.js Integration
For Next.js applications, you may need to use dynamic imports to avoid SSR issues:
import dynamic from 'next/dynamic';
import { useState } from 'react';
const ClassicEditor = dynamic(
() => import('smartrte-react').then(mod => mod.ClassicEditor),
{ ssr: false }
);
export default function Page() {
const [content, setContent] = useState('');
return (
<div>
<ClassicEditor
value={content}
onChange={setContent}
placeholder="Start typing..."
/>
</div>
);
}๐ง Features Deep Dive
Text Formatting
The editor supports all standard text formatting options:
- Bold, Italic, Underline,
Strikethrough - Font sizes from 8pt to 96pt
- Text color and background color
- Headings (H1-H6)
- Paragraph, blockquote, code block
- Ordered and unordered lists
- Text alignment (left, center, right, justify)
- Superscript and subscript
Tables
Full-featured table support includes:
- Create tables with custom rows and columns
- Add/delete rows and columns
- Merge and split cells
- Toggle header rows/cells
- Cell background colors
- Cell borders toggle
- Right-click context menu for table operations
- Keyboard navigation (Tab, Shift+Tab, Arrow keys)
Keyboard Shortcuts:
Tab- Move to next cellShift+Tab- Move to previous cellArrow keys- Navigate between cells- Right-click on cell - Open context menu
Mathematical Formulas
LaTeX/KaTeX support for mathematical expressions:
// The editor automatically loads KaTeX
// Users can insert formulas using the formula button
// Examples of supported LaTeX:
// - E=mc^2
// - \frac{a}{b}
// - \sqrt{x}
// - \sum_{i=1}^{n} x_iRequired External Dependency:
To use formulas, include KaTeX in your HTML:
<!-- In your public/index.html or _app.tsx -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js"></script>Media Management
Built-in image support with optional custom media manager:
Default behavior:
- Local file upload
- Drag and drop images
- Image resize handles
- Right-click context menu for image operations
Custom Media Manager Implementation:
import { MediaManagerAdapter, MediaItem, MediaSearchQuery } from 'smartrte-react';
const myMediaManager: MediaManagerAdapter = {
async search(query: MediaSearchQuery) {
// Search your media library
return {
items: [/* array of MediaItem */],
hasMore: false,
nextPage: undefined,
};
},
async upload(file: File) {
// Upload file to your server
return {
id: 'unique-id',
url: 'https://example.com/image.jpg',
thumbnailUrl: 'https://example.com/thumb.jpg',
title: 'Image title',
};
},
};๐จ Theming & Dark Mode
The editor uses CSS custom properties (CSS variables) for all colors, making it fully customizable. No hardcoded colors โ everything can be themed.
Quick Start: Dark Mode
<ClassicEditor theme="dark" onChange={handleChange} />Custom Themes via CSS
Apply a custom class and override any CSS variables:
<ClassicEditor className="my-theme" onChange={handleChange} />.my-theme {
--srte-bg: #1a1a2e;
--srte-text: #eaeaea;
--srte-border: #3a3a5c;
/* Override only the variables you need */
}Responding to System Preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
<ClassicEditor theme={prefersDark ? 'dark' : 'light'} />Or purely via CSS (without the theme prop):
@media (prefers-color-scheme: dark) {
.srte-editor {
--srte-bg: #1e1e1e;
--srte-text: #e0e0e0;
--srte-border: #3a3a3a;
/* ... */
}
}Available CSS Custom Properties
| Variable | Default (Light) | Description |
|---|---|---|
--srte-bg |
#ffffff |
Editor container & content background |
--srte-text |
#111111 |
Primary UI text color |
--srte-text-muted |
#4b5563 |
Secondary/subtle text |
--srte-border |
#dddddd |
Standard border color |
--srte-border-light |
#eeeeee |
Light separator borders |
--srte-toolbar-bg |
#ffffff |
Toolbar background |
--srte-input-bg |
#ffffff |
Button, input, select backgrounds |
--srte-input-text |
#111111 |
Button, input, select text |
--srte-input-border |
#e5e7eb |
Button, input, select borders |
--srte-modal-backdrop |
rgba(0,0,0,0.35) |
Modal overlay background |
--srte-modal-bg |
#ffffff |
Modal/dialog background |
--srte-modal-text |
#000000 |
Modal text color |
--srte-menu-bg |
#ffffff |
Context menu background |
--srte-menu-text |
#111111 |
Context menu text |
--srte-menu-shadow |
0 8px 24px rgba(0,0,0,0.18) |
Menu box-shadow |
--srte-accent |
#1e90ff |
Accent/selection color |
--srte-accent-bg |
rgba(30,144,255,0.15) |
Accent background (translucent) |
--srte-danger |
#dc2626 |
Destructive action color |
--srte-primary |
#2563eb |
Primary action button color |
--srte-surface-subtle |
#f3f4f6 |
Subtle surface (dropzone, preset buttons) |
--srte-on-primary |
#ffffff |
Text on primary/danger buttons |
--srte-cancel-bg |
#f3f4f6 |
Cancel button background |
Important Notes
- User content colors are preserved โ colors set via the color picker (text/background) are inline styles on content elements and are not affected by theming.
- Color picker swatches are not themed โ they display actual color values regardless of theme.
- The theme only affects editor chrome โ toolbar, dialogs, menus, and container. User content remains unchanged.
๐ ๏ธ Development
Prerequisites
- Node.js 18+
- pnpm 9.10.0+
Setting Up Development Environment
- Clone the repository
git clone https://github.com/ayush1852017/smart-rte.git
cd smart-rte- Install dependencies
pnpm install- Build the project
# Build TypeScript packages
pnpm build- Run the development playground
cd packages/react/playground
pnpm install
pnpm devThe playground will be available at http://localhost:5173
Project Structure
smart-rte/
โโโ packages/
โ โโโ react/ # Main React package (smartrte-react)
โ โโโ src/
โ โ โโโ components/
โ โ โ โโโ ClassicEditor.tsx # Main editor component
โ โ โ โโโ MediaManager.tsx # Media management component
โ โ โโโ index.ts
โ โโโ playground/ # Development playground
โ โโโ package.json
โโโ dart/ # Flutter/Dart packages
โ โโโ smartrte_flutter/ # Flutter WebView integration
โ โโโ example_app/ # Flutter example
โโโ package.jsonBuilding for Production
# Build the React package
cd packages/react
pnpm build
# This creates:
# - dist/index.js - ES module
# - dist/index.d.ts - TypeScript definitions
# - dist/embed.js - Standalone embed bundleRunning Tests
# Run vitest
pnpm test
# Run E2E tests with Playwright
pnpm e2eRunning Storybook
cd packages/react
pnpm storybookStorybook will be available at http://localhost:6006
๐ Publishing
For Package Maintainers
The package is published to npm as smartrte-react.
# Make sure you're in packages/react
cd packages/react
# Update version in package.json
# Then publish
pnpm publishThe prepublishOnly script automatically runs build:all before publishing.
Version Management
We follow Semantic Versioning:
- MAJOR version for incompatible API changes
- MINOR version for backwards-compatible functionality
- PATCH version for backwards-compatible bug fixes
๐ค Contributing
We welcome contributions! Here's how you can help:
Reporting Bugs
- Check if the bug has already been reported in Issues
- If not, create a new issue with:
- Clear title and description
- Steps to reproduce
- Expected vs actual behavior
- Screenshots if applicable
- Your environment (browser, OS, React version)
Suggesting Features
- Check existing feature requests
- Create a new issue with:
- Clear description of the feature
- Use cases
- Proposed API (if applicable)
Pull Requests
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test your changes thoroughly
- Commit with clear messages (
git commit -m 'Add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request
PR Guidelines
- Follow the existing code style
- Add tests for new features
- Update documentation
- Keep PRs focused on a single feature/fix
- Write clear commit messages
Development Workflow
# 1. Create a feature branch
git checkout -b feature/my-feature
# 2. Make changes and test
pnpm dev # Run playground
pnpm test # Run tests
# 3. Build to ensure no errors
pnpm build
# 4. Commit and push
git add .
git commit -m "feat: add my feature"
git push origin feature/my-feature
# 5. Create PR on GitHub๐ Troubleshooting
Common Issues
Issue: Editor not showing/rendering
Solution: Make sure React and React-DOM are installed as peer dependencies:
npm install react@18 react-dom@18Issue: Formula rendering not working
Solution: Ensure KaTeX is loaded in your HTML:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css">
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js"></script>Issue: TypeScript errors
Solution: Make sure you have the latest type definitions:
npm install --save-dev @types/react@18 @types/react-dom@18Issue: Build errors in Next.js
Solution: Use dynamic imports to disable SSR:
const ClassicEditor = dynamic(
() => import('smartrte-react').then(mod => mod.ClassicEditor),
{ ssr: false }
);Issue: Images not uploading
Solution: Check that the media prop is set to true and implement a custom mediaManager if you need server-side uploads.
๐ Security
Reporting Security Issues
If you discover a security vulnerability, please email [support@openstash.in] instead of using the issue tracker.
Content Sanitization
โ ๏ธ Important: The editor outputs raw HTML. Always sanitize user-generated content before displaying it to prevent XSS attacks.
Recommended libraries:
Example:
import DOMPurify from 'dompurify';
function DisplayContent({ html }) {
const sanitized = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
}๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2025 Smart RTE Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.๐ฅ Authors & Contributors
- Smart RTE Team - Initial work and maintenance
See the list of contributors who participated in this project.
๐ Acknowledgments
- KaTeX - For mathematical formula rendering
- React - The UI library
- Vite - Build tool
- All our amazing contributors
๐ Support
- Documentation: You're reading it! ๐
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Twitter: @smartrte (if applicable)
๐บ๏ธ Roadmap
Current Version (0.2.x)
- โ Rich text editing
- โ Table support
- โ Formula support (LaTeX/KaTeX)
- โ Media management
- โ TypeScript support
- โ Dark mode & theming (CSS custom properties)
Upcoming Features
- ๐ Collaborative editing
- ๐ Undo/Redo improvements
- ๐ Code syntax highlighting
- ๐ Markdown import/export
- ๐ Custom toolbar configuration
- ๐ Mobile optimization
- ๐ Accessibility improvements (ARIA labels, keyboard shortcuts)
๐ Browser Support
| Browser | Version |
|---|---|
| Chrome | Last 2 versions |
| Firefox | Last 2 versions |
| Safari | Last 2 versions |
| Edge | Last 2 versions |
๐ Related Packages
- smartrte-flutter - Flutter/Dart WebView implementation
๐ก Tips & Best Practices
- Performance: For large documents, consider implementing lazy loading or pagination
- State Management: Use React state or a state management library (Redux, Zustand) for complex applications
- Validation: Always validate and sanitize HTML content before storing or displaying
- Accessibility: Test with screen readers and keyboard navigation
- Mobile: Test on mobile devices as touch interactions may differ
- Auto-save: Implement auto-save functionality to prevent data loss
๐ Learning Resources
For Entry-Level Developers
- Getting Started with React: React Official Tutorial
- Understanding Rich Text Editors: MDN ContentEditable
- TypeScript Basics: TypeScript Handbook
For Mid-Level Developers
- Advanced React Patterns: Hooks, Context, Performance Optimization
- Component Design: Building reusable, maintainable components
- State Management: When and how to use external state management
For Senior Developers
- Architecture: Designing scalable editor implementations
- Performance: Optimization techniques for large documents
- Extensibility: Building plugin systems and custom extensions
- Cross-platform: Adapting the editor for different frameworks
Happy Editing! ๐
If you find this package useful, please consider giving it a โญ on GitHub!