textohtml
v1.0.1
Published
A powerful, feature-rich HTML editor built with React and TypeScript
Maintainers
Readme
TextoHTML
A powerful, feature-rich HTML editor built with React and TypeScript. This editor provides a comprehensive set of tools for creating rich text content with modern UI, full keyboard shortcut support, and inline CSS styling for maximum portability.
✨ Features
📝 Basic Text Editing
- Bold (Ctrl+B / Cmd+B)
- Italic (Ctrl+I / Cmd+I)
- Underline (Ctrl+U / Cmd+U)
- Strikethrough
- Subscript & Superscript
- Inline code formatting
- Remove formatting button
- Clear all content
- Paste without formatting (removes styles from pasted content)
🎨 Font & Typography Controls
Font Family
Choose from 7 predefined font families:
- Arial
- Helvetica
- Times New Roman
- Courier New
- Verdana
- Georgia
- Comic Sans MS
Font Size
- Preset sizes: 8px, 10px, 12px, 14px, 16px, 18px, 20px, 24px, 28px, 32px, 36px, 48px, 60px, 72px
- Custom font size input (any value in px)
Text Color
- 80-color palette (8 rows × 10 columns) including:
- Grayscale/Neutrals (10 shades)
- Bright/Saturated colors (Reds, Oranges, Yellows, Greens, Cyans, Blues, Purples, Magentas, Pinks)
- Pastel/Muted tones
- Earthy/Muted tones
- Custom color picker with:
- HSL (Hue, Saturation, Lightness) controls
- RGB (Red, Green, Blue) inputs
- Hex color input
- Visual gradient picker
- Real-time color preview
Background Color / Highlight
- Same 80-color palette
- Custom color picker (HSL/RGB/Hex)
- Perfect for highlighting text
Typography Controls
- Line height adjustment (numeric values)
- Letter spacing control
- Text capitalization options (uppercase, lowercase, capitalize)
📑 Paragraph & Block Formatting
Headings
- H1, H2, H3, H4, H5, H6 support
- Custom heading styles via props:
headingStyles={{ h1: { fontSize: '32px', fontWeight: 'bold', margin: '16px 0', lineHeight: '1.2' }, h2: { fontSize: '24px', fontWeight: 'bold', margin: '12px 0', lineHeight: '1.3' }, // ... h3, h4, h5, h6 }}
Block Elements
- Paragraph formatting with custom styles
- Blockquote styling
- Code block / Preformatted text (
<pre>) with syntax highlighting background - Horizontal rule / Divider (
<hr>)
Alignment
- Left alignment
- Center alignment
- Right alignment
- Justify alignment
Indentation
- Indent (increase left margin)
- Outdent (decrease left margin)
📋 Lists
Ordered Lists (Numbered)
- Decimal (1, 2, 3, ...)
- Lower Alpha (a, b, c, ...)
- Upper Alpha (A, B, C, ...)
- Lower Roman (i, ii, iii, ...)
- Upper Roman (I, II, III, ...)
- Automatic style variation for nested lists
Unordered Lists (Bulleted)
- Disc (•)
- Circle (○)
- Square (■)
- Diamond (◆) - Custom marker
- Arrow (→) - Custom marker
- Star (★) - Custom marker
- Triangle (▶) - Custom marker
- Automatic style variation for nested lists
List Features
- Nested lists support (unlimited nesting)
- Task/Checklist with checkboxes
- Automatic list style application
- Style preservation on indent/outdent
🔗 Links
- Insert link (Ctrl+K / Cmd+K)
- Edit existing link
- Remove link
- Open in new tab option (target="_blank")
- Remove link decoration option (no underline, no color change)
- Link preview on hover
- Visual link selection
🖼 Images
Insert Methods
- File upload via button
- Drag & drop images directly into editor
- Paste images from clipboard
- Image URL input
- Custom upload handler via
onImageUploadprop
Image Features
- Resize images with drag handles (responsive)
- Alignment options:
- Left (float left)
- Center (centered block)
- Right (float right)
- None (inline)
- Alt text support for accessibility
- Image captions (optional text below image)
- Image toolbar on selection:
- Edit properties
- Replace image
- Copy image
- Delete image
- Move up/down
- Resize
- Set alignment
- Base64 encoding support (images embedded in HTML)
📊 Tables
Table Creation
- Insert table with customizable:
- Rows (1-20+)
- Columns (1-20+)
- Header row option
Table Operations
- Add row (above or below selected row)
- Remove row
- Add column (left or right of selected column)
- Remove column
- Merge cells (horizontal and vertical)
- Split cells (undo merge)
- Delete table
Table Styling
- Header background color (default: #f3f4f6)
- Column background color (per column)
- Row background color (per row)
- Border color customization
- Border width control
- Cell padding adjustment
- Table alignment (left, center, right)
- Column width control
Table Interface
- Floating toolbar when table is selected
- Right-click context menu for quick operations
- Table properties panel for advanced styling
- Visual selection indicators
🎬 Media Embeds
Video
- YouTube embed (automatic URL parsing)
- Vimeo embed (automatic URL parsing)
- Direct video URL (MP4, WebM, etc.)
- Video controls (play, pause, volume)
- Resize video (width and height)
- Video alignment (left, center, right, none)
- Alt text support for accessibility
Audio
- Audio URL embed (MP3, WAV, OGG, etc.)
- Audio controls (play, pause, volume, seek)
- Resize audio player (width and height)
- Audio alignment (left, center, right, none)
Iframe
- Custom iframe embeds
- Any URL support (social media, maps, etc.)
- Resize iframe (width and height)
- Iframe alignment (left, center, right, none)
- Alt text support
Media Features
- Media toolbar on selection:
- Edit properties
- Replace media
- Copy media
- Delete media
- Move up/down
- Resize
- Set alignment
- Set alt text
- Responsive containers for all media types
⌨️ Keyboard Shortcuts
| Shortcut | Action |
|----------|--------|
| Ctrl+Z / Cmd+Z | Undo |
| Ctrl+Y / Ctrl+Shift+Z / Cmd+Shift+Z | Redo |
| Ctrl+B / Cmd+B | Bold |
| Ctrl+I / Cmd+I | Italic |
| Ctrl+U / Cmd+U | Underline |
| Ctrl+K / Cmd+K | Insert Link |
🔄 Undo/Redo & History
- Full undo/redo support
- History management (up to 50 states)
- Automatic history saving on content changes
- Keyboard shortcuts for history navigation
- Debounced history to prevent excessive saves
🎯 Additional Features
- Fullscreen mode (toggle button)
- Code view (HTML source editor)
- Visual view (WYSIWYG editor)
- Read-only mode (via
readOnlyprop) - Placeholder text (customizable)
- Custom height configuration (string or number)
- Modern, trending UI design
- Inline CSS styling (all styles embedded in HTML for portability)
- React Lucide icons (beautiful icon set)
- TypeScript support (full type definitions)
- Responsive design (works on all screen sizes)
- Tabbed toolbar (Text, Block, Media tabs for organized controls)
- Active formatting indicators (shows current formatting state)
- Selection preservation (maintains selection during operations)
📦 Installation
npm install textohtml🚀 Usage
Basic Example
import React, { useState } from 'react';
import { TextoHTML } from 'textohtml';
function App() {
const [content, setContent] = useState('');
return (
<TextoHTML
value={content}
onChange={setContent}
placeholder="Start typing..."
/>
);
}With Image Upload
import React, { useState } from 'react';
import { TextoHTML } from 'textohtml';
function App() {
const [content, setContent] = useState('');
const handleImageUpload = async (file: File): Promise<string> => {
// Upload file to your server
const formData = new FormData();
formData.append('image', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
const data = await response.json();
return data.url; // Return the image URL
};
return (
<TextoHTML
value={content}
onChange={setContent}
onImageUpload={handleImageUpload}
height={600}
/>
);
}With Custom Heading & Paragraph Styles
import React, { useState } from 'react';
import { TextoHTML } from 'textohtml';
function App() {
const [content, setContent] = useState('');
return (
<TextoHTML
value={content}
onChange={setContent}
headingStyles={{
h1: {
fontSize: '2.5rem',
fontWeight: 'bold',
margin: '1rem 0',
lineHeight: '1.2'
},
h2: {
fontSize: '2rem',
fontWeight: '600',
margin: '0.875rem 0',
lineHeight: '1.3'
},
h3: {
fontSize: '1.5rem',
fontWeight: '600',
margin: '0.75rem 0',
lineHeight: '1.4'
},
}}
paragraphStyles={{
margin: '0.5rem 0',
lineHeight: '1.6',
}}
/>
);
}Using Ref for Programmatic Control
import React, { useRef } from 'react';
import { TextoHTML, EditorRef } from 'textohtml';
function App() {
const editorRef = useRef<EditorRef>(null);
const handleSave = () => {
const content = editorRef.current?.getContent();
console.log('Saved content:', content);
// Content includes all inline styles
};
const handleClear = () => {
editorRef.current?.setContent('');
};
const handleInsertText = () => {
editorRef.current?.setContent('<p>Hello <strong>World</strong>!</p>');
};
const handleFocus = () => {
editorRef.current?.focus();
};
return (
<>
<TextoHTML
ref={editorRef}
onChange={(html) => console.log('Content changed:', html)}
/>
<div style={{ marginTop: '10px', display: 'flex', gap: '10px' }}>
<button onClick={handleSave}>Save</button>
<button onClick={handleClear}>Clear</button>
<button onClick={handleInsertText}>Insert Text</button>
<button onClick={handleFocus}>Focus Editor</button>
</div>
</>
);
}Read-Only Mode
import React from 'react';
import { TextoHTML } from 'textohtml';
function App() {
const content = '<p>This content is read-only</p>';
return (
<TextoHTML
value={content}
readOnly={true}
height={300}
/>
);
}📚 API Reference
Props
TextoHTMLProps
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | '' | The HTML content of the editor |
| onChange | (html: string) => void | - | Callback fired when content changes. Receives HTML with inline styles. |
| placeholder | string | 'Start typing...' | Placeholder text when editor is empty |
| height | string \| number | '500px' | Height of the editor (e.g., '600px' or 600) |
| readOnly | boolean | false | Whether the editor is read-only |
| onImageUpload | (file: File) => Promise<string> | - | Handler for image uploads. Should return the image URL. If not provided, images are converted to base64 data URIs. |
| className | string | '' | Additional CSS class name for the editor container |
| headingStyles | object | - | Custom styles for headings (see HeadingStyles interface) |
| paragraphStyles | object | - | Custom styles for paragraphs (see ParagraphStyles interface) |
HeadingStyles
interface HeadingStyles {
fontSize?: string;
fontWeight?: string | number;
margin?: string;
lineHeight?: string;
}ParagraphStyles
interface ParagraphStyles {
margin?: string;
lineHeight?: string;
}Ref Methods
EditorRef
| Method | Description |
|--------|-------------|
| getContent() | Returns the current HTML content with all inline styles applied |
| setContent(html: string) | Sets the HTML content. Styles are automatically applied. |
| focus() | Focuses the editor |
| blur() | Blurs the editor |
| execCommand(command: string, value?: string) | Executes a document command (e.g., 'bold', 'italic', 'insertHTML') |
| getStyles() | Returns editor styles information (currently returns a comment) |
TypeScript Support
Full TypeScript definitions are included:
import { TextoHTML, TextoHTMLProps, EditorRef } from 'textohtml';🎨 Styling
Inline Styles
TextoHTML uses inline CSS styling for all content. This means:
- All styles are embedded directly in the HTML
- Content is portable and self-contained
- No external CSS dependencies
- Styles are preserved when copying HTML
Custom Styles
You can customize heading and paragraph styles via props:
<TextoHTML
headingStyles={{
h1: { fontSize: '32px', fontWeight: 'bold' },
h2: { fontSize: '24px', fontWeight: '600' },
}}
paragraphStyles={{
margin: '1rem 0',
lineHeight: '1.6',
}}
/>Editor Container
The editor container can be styled using the className prop:
<TextoHTML
className="my-custom-editor"
// ... other props
/>🌐 Browser Support
- ✅ Chrome (latest)
- ✅ Firefox (latest)
- ✅ Safari (latest)
- ✅ Edge (latest)
🛠️ Development
# Install dependencies
npm install
# Build the package
npm run build
# Watch mode for development
npm run dev
# Run test server
npm run test📝 Notes
Image Handling
- If
onImageUploadis provided, images are uploaded to your server - If
onImageUploadis not provided, images are automatically converted to base64 data URIs - Base64 images are embedded directly in the HTML output
Content Format
- All content uses inline styles for maximum portability
- HTML output is cleaned and optimized
- Styles are automatically applied to maintain formatting
History Management
- History is automatically saved on content changes
- Maximum of 50 history states
- History is debounced to prevent excessive saves
📄 License
MIT
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
🔗 Links
- GitHub Repository: https://github.com/edvertotech/textohtml
- npm Package: https://www.npmjs.com/package/textohtml
- Issues: https://github.com/edvertotech/textohtml/issues
Made with ❤️ using React and TypeScript
