strata-editor
v2.1.1
Published
A production-ready CodeMirror 6 markdown editor with Obsidian-style WYSIWYG editing
Downloads
989
Maintainers
Readme
Strata Editor
A production-ready CodeMirror 6 markdown editor with Obsidian-style WYSIWYG editing.
🔗 Live Demo • Documentation • Contributing
Features
- 📝 WYSIWYG Editing — Markdown syntax hides when not editing (like Obsidian)
- 🔗 Wikilinks —
[[note]],[[note|alias]],[[note#heading]] - 📌 Callouts —
> [!info],> [!warning], foldable support - 🏷️ Tags —
#tagand#nested/tagwith click handlers - 🖼️ Images —
![[image.png]]embedding - 🦶 Footnotes —
[^1]reference and definition - 🔦 Highlights —
==highlighted text== - 📊 Tables — GFM tables with full formatting
- 🧮 Math — LaTeX/KaTeX rendering (via extension)
- 🎨 Theming — Full CSS variable system, light/dark modes
- 🔌 Extensible — Simple API for custom syntax
- 🛡️ Error Boundary — Graceful error handling
Installation
npm install strata-editor @codemirror/autocomplete @codemirror/commands @codemirror/lang-markdown @codemirror/language @codemirror/state @codemirror/view @lezer/highlight @lezer/markdownOr with specific CodeMirror versions you already have:
npm install strata-editorPeer Dependencies:
- React 18+ or 19+
- CodeMirror 6 packages (see above)
Quick Start
import { MarkdownEditor, EditorErrorBoundary, createThemeStyles, mathExtension } from 'strata-editor';
function App() {
const [content, setContent] = useState('# Hello World');
const themeStyles = createThemeStyles({ mode: 'dark' });
return (
<div style={themeStyles}>
<EditorErrorBoundary>
<MarkdownEditor
value={content}
onChange={setContent}
onWikilinkClick={(data) => console.log('Navigate to:', data.target)}
onTagClick={(tag) => console.log('Filter by:', tag)}
extensions={[mathExtension()]}
/>
</EditorErrorBoundary>
</div>
);
}Theming
Strata uses a host-app-first theming approach. Generate CSS variables with createThemeStyles():
import { createThemeStyles } from 'strata-editor';
const theme = {
mode: 'dark',
colors: { background: '#1a1a2e' },
code: { keyword: '#ff79c6' }
};
const styles = createThemeStyles(theme);
// Apply styles to a container divSee Theming Documentation for full customization options.
Custom Extensions
Add your own syntax support:
import { createExtension } from 'strata-editor';
const mentions = createExtension({
name: 'mention',
pattern: /@(\w+)/g,
className: 'cm-mention',
onClick: (match) => alert(`User: @${match[1]}`),
});
<MarkdownEditor extensions={[mentions]} />API Reference
MarkdownEditor Props
| Prop | Type | Description |
|------|------|-------------|
| value | string | Controlled markdown content |
| defaultValue | string | Initial content (uncontrolled) |
| onChange | (value: string) => void | Content change handler |
| placeholder | string | Placeholder text |
| readOnly | boolean | Read-only mode |
| extensions | Extension[] | Additional CM6 extensions |
| onWikilinkClick | (data, e) => void | Wikilink click handler |
| onTagClick | (tag, e) => void | Tag click handler |
| wikilinkInteraction | 'click' \| 'modifier' | Trigger mode (default: modifier) |
| tagInteraction | 'click' \| 'modifier' | Trigger mode (default: modifier) |
Ref Methods
const editorRef = useRef<MarkdownEditorHandle>(null);
editorRef.current?.getValue(); // Get content
editorRef.current?.setValue(text); // Set content
editorRef.current?.focus(); // Focus editor
editorRef.current?.insertText(text); // Insert at cursor
editorRef.current?.wrapSelection('**', '**');// Wrap selectionDocumentation
| Guide | Description | |-------|-------------| | AI Integration | AI streaming & replace patterns | | Theming | CSS variables, custom themes | | Extensions | Creating custom syntax | | Callouts | All callout types | | Tables | Markdown table support | | Math | LaTeX/KaTeX rendering | | Architecture | Editor internals |
Contributing
We welcome contributions! See our GitHub Guide for setup and PR guidelines.
License
MIT
