@inkami/blx
v0.17.3
Published
A block-based editor library
Readme
@inkami/blx
A block-based editor for the web. Notion-style editing — rich text, media, tables, nesting — in a single TypeScript library with zero framework dependencies.
Install
npm install @inkami/blxQuick Start
import { Editor, AttributedString } from "@inkami/blx";
import "@inkami/blx/style.css";
const editor = new Editor(document.getElementById("editor")!, {
initialBlocks: [
{
id: "1",
type: "paragraph",
content: AttributedString.fromPlain("Hello, world!"),
metadata: {},
},
],
});Features
| | |
|---|---|
| Rich text | Bold, italic, underline, strikethrough, inline code, highlights (6 colors) |
| Block types | Paragraphs, headings (1-6), ordered/unordered lists, task lists, code (syntax highlighted), images, YouTube embeds, tables, horizontal rules |
| Links | Inline links with [markdown](syntax), Cmd+K popover, [[ internal block references with autocomplete |
| Editing | Slash menu, inline toolbar, block action menu, drag handles, multi-block selection |
| Search | Cmd+F with regex, case-sensitive toggle, find & replace |
| Undo/Redo | Transaction-based history with smart grouping |
| Nesting | Tab/Shift+Tab for lists and task lists, 4 indent levels |
| Theming | Light & dark mode via CSS custom properties |
| Extensible | Custom block types, toolbar buttons, block actions, slash menu items, autocomplete providers |
Custom Block Types
import type { BlockTypePlugin } from "@inkami/blx";
const calloutPlugin: BlockTypePlugin = {
type: "callout",
label: "Callout",
hasTextContent: true,
defaultContent: () => AttributedString.empty(),
defaultMetadata: () => ({ emoji: "💡" }),
render(container, content, metadata) {
// Build your DOM from the model
},
};
editor.registerBlockType(calloutPlugin);API
Editor
| Method | Description |
|---|---|
| new Editor(root, options?) | Create editor |
| addBlock(typeOrBlock, index?) | Add a block |
| removeBlock(id) | Remove a block |
| moveBlock(id, toIndex) | Reorder a block |
| changeBlockType(id, newType) | Convert block type |
| focusBlock(id, offset?) | Focus a block |
| registerBlockType(plugin) | Register a custom block type |
| addToolbarButton(config) | Add inline toolbar button |
| addBlockActionItem(config) | Add block action menu item |
| addSlashMenuItem(config) | Add slash menu entry |
| addAutoCompleteProvider(provider) | Add [[ autocomplete provider |
| toJSON() / Editor.fromJSON() | Serialize / restore |
| destroy() | Clean up |
AttributedString
| Method | Description |
|---|---|
| AttributedString.empty() | Create empty string |
| AttributedString.fromPlain(text, attrs?) | Create from plain text |
| .insertAt(offset, text, attrs?) | Insert text |
| .deleteRange(start, end) | Delete range |
| .applyAttributes(start, end, attrs) | Apply formatting |
| .removeAttributes(start, end, keys) | Remove formatting |
| .slice(start, end) | Extract substring |
| .concat(other) | Concatenate |
| .toJSON() / AttributedString.fromJSON() | Serialize / restore |
License
MIT
