@void/lexis-editor (0.2.0)
Installation
@void:registry=npm install @void/lexis-editor@0.2.0"@void/lexis-editor": "0.2.0"About this package
Lexis Editor
A drop-in rich text editor built on Lexical, packaged as a form-native web component.
Why Lexis Editor?
- Zero config — Add
<lexis-editor>to any form and it just works - Markdown native — Built-in markdown import/export, toggle with one option
- Form integration — Works with native HTML forms, validation, reset/restore
- Extensible — Add features by implementing
LexisExtensionclasses - Toolbar included — Built-in toolbar with familiar formatting controls
Installation
npm install @void/lexis-editor
// main.js
import '@void/lexis-editor';
import '@void/lexis-editor/lexis-editor.css';
import '@void/lexis-editor/lexis-content.css';
Quick Start
<form method="get">
<lexis-editor
name="content"
value="# Hello World"
placeholder="Write something..."
></lexis-editor>
<button type="submit">Save</button>
</form>
That's it. The editor handles form submission, validation, and content serialization automatically.
Examples
Full-Featured Editor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Blog Editor</title>
<script type="module">
import '@void/lexis-editor';
import '@void/lexis-editor/lexis-editor.css';
import '@void/lexis-editor/lexis-content.css';
const editor = document.querySelector('lexis-editor');
// Configure before initialization
editor.addEventListener('editor:initialize', (e) => {
e.detail.configure({
markdown: true,
toolbar: {
template: 'format list link ~ history'
}
});
});
// Listen for changes
editor.addEventListener('editor:change', (e) => {
console.log('Content:', e.detail.value);
});
</script>
</head>
<body>
<form>
<lexis-editor
name="post"
value="## Title\n\nStart writing..."
required
placeholder="Enter your post content..."
></lexis-editor>
<button type="submit">Publish</button>
<button type="reset">Reset</button>
</form>
</body>
</html>
Image Upload Handler
import '@void/lexis-editor';
// Handle image file uploads
document.addEventListener('editor:image:upload', (event) => {
const { file, upload } = event.detail;
// file.name — the uploaded filename
// upload.progress(n) — update progress (0-100)
// upload.success({ url }) — signal completion
// upload.error(message) — signal failure
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload');
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
upload.progress((e.loaded / e.total) * 100);
}
};
xhr.onload = () => {
if (xhr.status === 200) {
const { url } = JSON.parse(xhr.responseText);
upload.success({ url });
} else {
upload.error('Upload failed');
}
};
xhr.send(file);
});
Features
| Text | Blocks | Media | Output |
|---|---|---|---|
| Bold, italic, underline | Headings (1-4) | Images (URL or file) | Markdown |
| Strikethrough, inline code | Blockquotes | Links with validation | Sanitized HTML |
| — | Code blocks (Prism) | — | — |
| — | Bullet/numbered lists | — | — |
| — | Horizontal dividers | — | — |
Configuration
Configure via the editor:initialize event:
element.addEventListener('editor:initialize', (e) => {
e.detail.configure({
markdown: true, // Output format: true=markdown, false=HTML
extensionMode: 'append', // 'append' or 'replace'
extensions: [], // Custom LexisExtension classes
lexical: {
namespace: '@my/editor',
theme: { // Custom CSS class mappings
text: { bold: 'my-bold' }
}
},
toolbar: {
template: 'format | list link',
groups: { list: ['bullet-list', 'number-list' ]} // Named command groups
}
});
});
Available Options
| Option | Type | Default | Description |
|---|---|---|---|
markdown |
boolean | true |
Serialize as markdown or HTML |
extensions |
array | [] |
Add custom extensions |
extensionMode |
string | 'append' |
How to merge extensions |
toolbar |
object | {} |
Toolbar template and groups |
lexical |
object | {} |
Lexical namespace and theme |
Toolbar Configuration
The toolbar uses a token-based template system.
Template Syntax
| Token | Description |
|---|---|
| |
Separator between controls |
~ |
Spacer (flex gap) |
command-id |
Single command button (e.g., bold, italic) |
group-name |
Dropdown group (requires toolbar.groups) |
| Extension token | Custom control from extension (e.g., link) |
Built-in Command Tokens
Format:
bold,italic,underline,strikethrough,code
Lists:
bullet-list,number-list
Blocks:
heading-1,heading-2,heading-3,heading-4quote,paragraph,divider,code-block
Media:
link(extension-provided, shows popover)insert-image
History:
undo,redo
Groups
Create dropdown groups by defining toolbar.groups:
e.detail.configure({
toolbar: {
template: 'format headings history',
groups: {
headings: ['heading-1', 'heading-2', 'heading-3', 'paragraph']
}
}
});
Disabling Toolbar
<lexis-editor toolbar="false"></lexis-editor>
Events
| Event | Description |
|---|---|
editor:initialize |
Configure before ready (cancelable config patch) |
editor:ready |
Editor initialized, detail.editor available |
editor:change |
Content changed, detail.value contains current content |
editor:focus |
Editor gained focus |
editor:blur |
Editor lost focus |
editor:image:insert |
Image about to insert (call preventDefault() to cancel) |
editor:image:upload |
Image file upload with progress callbacks |
API
After editor:ready:
const { editor } = event.detail;
// Content
editor.value // Markdown or HTML string
editor.textValue // Plain text
editor.isEmpty // Boolean
// Commands
editor.runCommand('bold');
editor.runCommand('heading-2');
// State
editor.isActive('italic'); // true/false
editor.isDisabled('undo'); // true/false
Available Commands
| Category | Commands |
|---|---|
| Format | bold, italic, underline, strikethrough, code |
| Lists | bullet-list, number-list |
| Blocks | heading-1, heading-2, heading-3, heading-4, quote, paragraph, divider, code-block |
| Media | link, unlink, insert-image |
| History | undo, redo |
Development
npm install # Install dependencies
npm run dev # Start dev server
npm run build # Build for production
npm run build:check # Biome check
npm run lint # Biome lint
The index.html file provides a working demo with toolbar, form integration, and image upload simulation.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @lexical/code | ^0.42.0 |
| @lexical/code-prism | ^0.42.0 |
| @lexical/extension | ^0.42.0 |
| @lexical/history | ^0.42.0 |
| @lexical/html | ^0.42.0 |
| @lexical/link | ^0.42.0 |
| @lexical/list | ^0.42.0 |
| @lexical/markdown | ^0.42.0 |
| @lexical/rich-text | ^0.42.0 |
| @lexical/utils | ^0.42.0 |
| dompurify | ^3.4.0 |
| lexical | ^0.42.0 |
| marked | ^18.0.0 |
| prismjs | ^1.30.0 |
Development dependencies
| ID | Version |
|---|---|
| @biomejs/biome | ^2.4.10 |
| puppeteer-core | ^25.10.0 |
| sanitize.css | ^13.0.0 |
| vite | ^8.0.1 |
Details
Assets (1)
Versions (6)
View all
lexis-editor-0.2.0.tgz
46 KiB