@fewings/text-editor v1.0.2

Motivation
There are already many excellent text editor libraries available. However, most of them are close to being complete solutions, making it cumbersome to add or remove features and modify designs as it requires deep understanding of their internal structure.
@fewings/text-editor addresses this inconvenience by providing only core functionality in API form. Users can choose the features they need and compose UI in a completely flexible way.
It doesn't even include basic styles, requiring you to design based on the defined DOM structure, data-attributes, and class properties. Additionally, it provides Selection and Range related APIs designed to support this approach.
🙏 This documentation doesn't cover all features. It introduces core functionality with a low level of abstraction and complexity that should be easy to understand. Please refer to
src/__test__,src/core, and sample code.
Installation
# npm
npm install @fewings/text-editor
# yarn
yarn add @fewings/text-editor
# pnpm
pnpm add @fewings/text-editorGetting Started
1. Creating a TextEditor instance
The text editor works on a DOM basis. First, prepare the HTML element where the editor will be rendered.
<div id="editor-container"></div>import { TextEditor } from "@fewings/text-editor";
// Get the editor container element
const editorElement = document.getElementById("editor-container");
// Create TextEditor instance
const editor = new TextEditor({
element: editorElement,
initialHtml:
"<div data-block-id='w1u2oultf'>Hello, this is a text editor.</div>", // Initial HTML content ⚠️ Must follow the DOM structure mentioned earlier (direct child elements must be HTMLDivElement with data-block-id)
mode: "edit", // Specify 'edit' or 'view' mode
spellcheck: true, // Enable or disable spell checking
});2. Listening to events
TextEditor provides several core events (more coming soon).
// Cursor position change event
editor.on("cursorChanged", (cursorStatus) => {
console.log("Current cursor status:", cursorStatus);
// cursorStatus object contains style information about the currently selected text:
// isH1, isBold, isItalic, color, bgColor, etc.
// You can use this information to update toolbar active states
});
// HTML content change event
editor.on("onChange", (html) => {
console.log("Editor content changed:", html);
// You can save or process the changed HTML
});
// Block add event (triggered whenever a new line is added)
editor.on("blockAdded", (blockElement) => {
console.log("New block added:", blockElement);
});3. Applying styling actions
You can apply various text styling and formatting actions.
// Apply bold
document.getElementById("bold-button").addEventListener("click", () => {
editor.action("bold");
});
// Apply italic
document.getElementById("italic-button").addEventListener("click", () => {
editor.action("italic");
});
// Apply heading style
document.getElementById("h1-button").addEventListener("click", () => {
editor.action("heading", "h1");
});
// Change text color
document.getElementById("color-picker").addEventListener("change", (e) => {
editor.action("color", e.target.value);
});
// Insert link
document.getElementById("link-button").addEventListener("click", () => {
const url = prompt("Enter URL");
if (url) {
editor.action("link", url);
}
});4. Easy usage in React
In React applications, you can use the provided components and hooks to use the editor more easily.
import { useState } from "react";
import {
TextEditorBody,
TextEditorProvider,
TextEditorView,
} from "@fewings/text-editor";
const initialHtml =
"<div data-block-id='w1u2oultf'>Hello, this is a text editor.</div>";
interface Props {
mode?: "edit" | "view";
spellcheck?: boolean;
showPreview?: boolean;
}
export default function SampleTextEditor({
mode,
spellcheck,
showPreview,
}: Props) {
const [preview, setPreview] = useState(initialHtml);
return (
<div>
<TextEditorProvider
onChange={setPreview}
initialHtml={initialHtml}
mode={mode}
spellcheck={spellcheck}
>
<div className="editor_layout">
<TextEditorBody style={{ height: 400, overflowY: "scroll" }} />
</div>
</TextEditorProvider>
{showPreview && <TextEditorView html={preview} className="preview" />}
</div>
);
}5. Getting and setting editor HTML content
// Get current editor content as HTML string
const html = editor.toHtml();
// Set editor content
editor.setHtml("<p>This is new content.</p>");
// Change editor mode (edit/read-only)
editor.setMode("view"); // Change to read-only
editor.setMode("edit"); // Change to editable6. Cleaning up the editor
After usage, clean up event listeners and resources.
When using
<TextEditorProvider>, cleanup is handled internally.
// Clean up editor instance
editor.destroy();Contributing
Contributions are welcome! If you have suggestions, bug reports, or feature requests, please open an issue or submit a pull request on the GitHub repository.