-
Notifications
You must be signed in to change notification settings - Fork 2
Advanced Features
Deep dives into tables, images, video, floating toolbar, block reordering, autosave, Find & Replace, and more.
Click the Insert → Table button. A dialog lets you configure:
- Rows — number of rows
- Columns — number of columns
-
Header row — optional first row as
<th>elements
Right-click any table cell to access:
| Action | Description |
|---|---|
| Insert Row Above | Add a row above the current cell |
| Insert Row Below | Add a row below the current cell |
| Insert Column Left | Add a column to the left |
| Insert Column Right | Add a column to the right |
| Delete Row | Remove the current row |
| Delete Column | Remove the current column |
| Delete Table | Remove the entire table |
| Merge Cells | Merge selected cells horizontally (colspan) |
| Split Cell | Split a previously merged cell back to individual cells |
Tip
To select multiple cells for merging: click the first cell, hold Shift, click the last cell in the same row, then right-click → Merge Cells.
Hover near the border between two columns — a vertical drag handle appears. Drag it to resize:
- The table switches to
table-layout: fixedduring resize - Adjacent columns are resized proportionally
- Minimum column width is 40px
- Works on both
<td>and<th>cells - The handle appears when the cursor is within 6px of a column border
Tables are rendered with default styles from neiki-editor.css:
- Bordered cells with subtle grid lines
- Header row with distinct background color
- Responsive 100% width
- Compatible with all 4 built-in themes
Neiki's Editor supports five ways to insert images:
Click Insert → Image, paste a URL. Inserted as a standard <img> tag.
The image dialog supports multiple file selection. All selected images are inserted sequentially.
-
Without
imageUploadHandler: images are read viaFileReaderand embedded as base64 data URIs -
With
imageUploadHandler: each file is passed to your async handler, the returned URL is inserted as<img src="...">
new NeikiEditor('#editor', {
imageUploadHandler: async (file) => {
const formData = new FormData();
formData.append('image', file);
const res = await fetch('/api/upload', { method: 'POST', body: formData });
const data = await res.json();
return data.url;
}
});Tip
Using imageUploadHandler is strongly recommended for production — it prevents bloated base64 content and enables browser caching.
Caution
Without imageUploadHandler, base64-encoded images significantly increase the HTML content size. For large images or production use, configure the upload handler.
Drag image files directly into the editor content area. The editor detects the drop, uploads or reads as base64, and inserts each image at the drop position.
Copy an image to your clipboard (screenshot, right-click → Copy Image) and paste with Ctrl+V. Works with or without imageUploadHandler.
Click any image to select it. Resize handles appear on all four corners (NW, NE, SW, SE):
- Drag any handle to resize
- Aspect ratio is always maintained
- A live size label (e.g.
640 × 480) appears below the image while resizing - Minimum size: 30px wide
- Click outside to deselect
When an image is selected, a contextual toolbar appears:
| Button | Description |
|---|---|
| ⠿ Drag handle | Click and drag to reposition the image |
| Replace | Open file picker to swap the current image |
| Delete | Remove the selected image |
Note
The floating text-formatting toolbar is automatically hidden when an image is selected — only image-specific actions are shown.
Insert videos via Insert → Video:
- URL input — paste any video URL
-
File upload — converted to base64 or uploaded via
videoUploadHandler - Drag & drop — drag a video file into the editor
new NeikiEditor('#editor', {
videoUploadHandler: async (file) => {
const formData = new FormData();
formData.append('video', file);
const response = await fetch('/api/upload-video', { method: 'POST', body: formData });
const data = await response.json();
return data.url;
}
});Inserted videos render as <video controls> elements. They can be resized and repositioned just like images.
Four built-in themes:
| Theme | Key | Description |
|---|---|---|
| Light | 'light' |
Clean white background, dark text. Default. |
| Dark | 'dark' |
Dark background, light text. Easy on the eyes. |
| Blue | 'blue' |
Bright blue interface, white canvas. |
| Dark Blue | 'dark-blue' |
Deep blue interface, blue accents. |
At initialization:
new NeikiEditor('#editor', { theme: 'dark' });Programmatically:
editor.setTheme('dark-blue');
editor.toggleTheme(); // cycle: light → dark → blue → dark-blue → lightVia the More menu (⋯): The Change theme select lets users pick any theme.
Important
The selected theme is persisted to localStorage as a global setting. This means:
- It applies to all editor instances on the page
- It persists across page reloads
- If the user selected dark mode, it remains dark even if you set
theme: 'light'in config — user preference always takes priority
The dark theme applies the CSS class neiki-dark to the editor container. Target it for custom dark-mode styles:
.neiki-dark .my-custom-element {
background: #1e1e1e;
color: #e0e0e0;
}| Code | Language |
|---|---|
en |
English (default) |
cs |
Czech |
zh |
Chinese |
es |
Spanish |
de |
German |
fr |
French |
pt |
Portuguese |
ja |
Japanese |
new NeikiEditor('#editor', {
language: 'cs'
});- All toolbar button tooltips
- Modal dialog labels (Link, Image, Table, Find & Replace)
- Status bar texts (word count, character count, block type)
- Autosave status messages
- System messages and confirmations
Override any translation key via the translations option:
new NeikiEditor('#editor', {
language: 'en',
translations: {
'toolbar.bold': 'Make Bold',
'placeholder': 'Start writing here...'
}
});Note
The language option must be set at initialization. Changing it at runtime requires re-initializing the editor.
Open via the findReplace toolbar button. The bar appears at the top of the editor content area.
| Feature | Description |
|---|---|
| Search field | Type text to find |
| Replace field | Type replacement text |
| Case Sensitive | Toggle — when active, Hello ≠ hello
|
| Regex Mode | Toggle — enables JS RegExp patterns |
| Find Next | Jump to and highlight the next match |
| Replace | Replace the current highlighted match |
| Replace All | Replace all occurrences at once |
| Pattern | Matches |
|---|---|
\b\w+\b |
Every word |
\d{4} |
4-digit numbers |
https?://\S+ |
URLs |
<em>.*?</em> |
Italic-wrapped text |
Autosave is accessible via the More menu (⋯).
- User enables Autosave from the More menu
- A badge shows the autosave status (✓ active, ✕ inactive)
- Content is saved to
localStorageon every change - The status bar shows "Autosaving..." / "Saved locally"
- On next page load with autosave still enabled, content is restored automatically
Autosave storage is scoped to page URL + editor identity by default. For isolation across records on the same URL, use autosaveKey:
new NeikiEditor('#editor', {
autosaveKey: 'article-42'
});Caution
Autosave is designed for development and draft recovery. For production, use onSave or onChange callbacks to save to your backend:
new NeikiEditor('#editor', {
onChange: debounce(function(content) {
fetch('/api/save', { method: 'POST', body: JSON.stringify({ content }) });
}, 2000)
});A context-sensitive toolbar that appears automatically when text is selected.
| Position | Buttons | Description |
|---|---|---|
| Left | ▲ ▼ | Move current block up / down |
| Right |
B I U |
Bold, Italic, Underline, Strikethrough, Link |
- Appears above the selection, follows cursor
- Disappears when selection is cleared
- Move Up / Down reorders the entire top-level block containing the selection
- When an image is selected, the floating toolbar is replaced by the image-specific toolbar
Note
The floating toolbar is always enabled and cannot be disabled or customized through config.
Hover over any content block to reveal a grip handle (⠿) on the left margin:
- Move cursor near any top-level block (paragraph, heading, table, image, list, blockquote)
- A grip icon (⠿) appears on the left
- Click and drag to a new position
- A ghost preview follows the cursor
- A dashed placeholder shows the target drop position
- Release to drop
Undo/Redo records block moves. onChange fires after each move.
Tip
You can also use the ▲ ▼ buttons in the floating toolbar for keyboard-friendly block reordering.
The status bar sits at the bottom of the editor:
| Position | Content |
|---|---|
| Left | Word count and character count |
| Right | Autosave status (when enabled) and current block type (p, h1, h2, h3, etc.) |
Updates automatically as you type or move the cursor.
Click More → Print to print the editor content:
- Opens a new browser window
- Copies the editor's HTML content with basic print styling
- Triggers the browser's native print dialog
- Closes the print window after printing
The printed output includes only the content — no toolbar, status bar, or editor chrome.
| ⚙️ Configuration | All config options including imageUploadHandler, autosaveKey
|
| 🎨 Themes & Styling | CSS customization and theme details |
| 📋 API Reference |
setTheme, toggleTheme, insertHTML and all methods |
| 🔒 Security | Sanitization details |
Getting Started
Reference
Extending
Integration
Features & UI
Project