### Install and Configure Marker Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the marker plugin to highlight text. ```bash npm i @editorjs/marker ``` ```javascript marker: { class: Marker, shortcut: 'CMD+SHIFT+M' } ``` -------------------------------- ### Install and Configure Underline Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the underline plugin to underline text. ```bash npm i @editorjs/underline ``` ```javascript underline: { class: Underline, shortcut: 'CMD+U' } ``` -------------------------------- ### Install and Configure Warning Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the warning plugin and add it to the Editor.js configuration. ```bash npm i @editorjs/warning ``` ```javascript warning: { class: Warning, inlineToolbar: true, config: { titlePlaceholder: 'Title', messagePlaceholder: 'Message' } } ``` -------------------------------- ### Install and Configure Table Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the table plugin and configure rows, columns, and headings. ```bash npm i @editorjs/table ``` ```javascript table: { class: Table, inlineToolbar: true, config: { rows: 2, cols: 3, withHeadings: true } } ``` -------------------------------- ### Install Warning Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Warning tool package via npm. ```bash npm i @editorjs/warning ``` -------------------------------- ### Install Code and Delimiter Tools Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Code and Delimiter tool packages via npm. ```bash npm i @editorjs/code @editorjs/delimiter ``` -------------------------------- ### Install and Configure Simple Image Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the simple image plugin for base64 or direct URL storage without a backend. ```bash npm i @editorjs/simple-image ``` ```javascript image: SimpleImage ``` -------------------------------- ### Install Image Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Image tool package via npm. ```bash npm i @editorjs/image ``` -------------------------------- ### Install and Configure Delimiter Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the delimiter plugin and add it to the Editor.js configuration. ```bash npm i @editorjs/delimiter ``` ```javascript delimiter: Delimiter ``` -------------------------------- ### Install Embed Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Embed tool package via npm. ```bash npm i @editorjs/embed ``` -------------------------------- ### Install and Configure Embed Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the embed plugin and configure supported services or custom regex-based services. ```bash npm i @editorjs/embed ``` ```javascript embed: { class: Embed, config: { services: { youtube: true, vimeo: true, codepen: true, github: true, twitter: true, // Custom service myService: { regex: /https?:\/\/mysite\.com\/embed\/(.+)/, embedUrl: 'https://mysite.com/embed/<%= remote_id %>', html: '', height: 300, width: 600 } } } } ``` -------------------------------- ### Install and Configure Quote Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the quote plugin and add it to the Editor.js configuration. ```bash npm i @editorjs/quote ``` ```javascript quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote author' } } ``` -------------------------------- ### Install and Configure Code Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the code plugin. Note that it enables line breaks by default. ```bash npm i @editorjs/code ``` ```javascript code: { class: Code } ``` -------------------------------- ### Install Inline Tools Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Marker, Underline, and Inline Code tool packages via npm. ```bash npm i @editorjs/marker @editorjs/underline @editorjs/inline-code ``` -------------------------------- ### Install and Configure Header Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Header tool using npm. Configure it with inline toolbar, placeholder text, heading levels, and a default level. ```bash npm i @editorjs/header ``` ```javascript import Header from '@editorjs/header'; const editor = new EditorJS({ tools: { header: { class: Header, inlineToolbar: true, config: { placeholder: 'Enter a heading', levels: [1, 2, 3, 4, 5, 6], defaultLevel: 2 } } } }); // Output: { "type": "header", "data": { "text": "My Heading", "level": 2 } } ``` -------------------------------- ### Editor.js Decision Tree Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md A visual guide for navigating Editor.js setup and configuration tasks. ```text Working with Editor.js? ├─ Setting up from scratch → Installation + Full Configuration ├─ Adding a content block → Official Block Tools ├─ Adding text formatting → Inline Tools (Marker, Underline, etc.) ├─ Block-level options → Block Tunes ├─ Building a custom block → Tools API (Custom Block Tool) ├─ Building a custom inline format → Tools API (Custom Inline Tool) ├─ Display content read-only → Read-Only Mode ├─ Multi-language support → i18n ├─ Rendering content on server → Server-Side Rendering (JS/PHP/Python) ├─ Framework integration → React / Vue / Vanilla JS examples └─ TypeScript project → TypeScript Support section ``` -------------------------------- ### Install editorjs-text-alignment-blocktune Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the community plugin for block-level text alignment using npm. ```bash npm i editorjs-text-alignment-blocktune ``` -------------------------------- ### Install and Configure List Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the List tool using npm. Configure it with an inline toolbar and a default list style (ordered or unordered). ```bash npm i @editorjs/list ``` ```javascript import List from '@editorjs/list'; const editor = new EditorJS({ tools: { list: { class: List, inlineToolbar: true, config: { defaultStyle: 'unordered' } } } }); // Output: { "type": "list", "data": { "style": "ordered", "items": ["First", "Second"] } } ``` -------------------------------- ### Install editorjs-hyperlink Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the community plugin for adding hyperlinks to content using npm. ```bash npm i editorjs-hyperlink ``` -------------------------------- ### Install Editor.js Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Use npm to install the Editor.js package. This is the first step to integrating the editor into your project. ```bash npm i @editorjs/editorjs --save ``` -------------------------------- ### Install and Configure Raw HTML Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the raw HTML plugin and add it to the Editor.js configuration. ```bash npm i @editorjs/raw ``` ```javascript raw: { class: Raw, config: { placeholder: 'Enter raw HTML' } } ``` -------------------------------- ### Install and Configure Inline Code Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the inline code plugin to format text as code. ```bash npm i @editorjs/inline-code ``` ```javascript inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' } ``` -------------------------------- ### Install editorjs-text-color-plugin Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the community plugin for text coloring and background highlighting using npm. ```bash npm i editorjs-text-color-plugin ``` -------------------------------- ### Install and Configure Table Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Table tool using npm. Configure with inline toolbar, number of rows and columns, and option for a header row. ```bash npm i @editorjs/table ``` ```javascript import Table from '@editorjs/table'; const editor = new EditorJS({ tools: { table: { class: Table, inlineToolbar: true, config: { rows: 2, cols: 3, withHeadings: true } } } }); // Output: // { // "type": "table", // "data": { // "withHeadings": true, // "content": [["Name", "Role"], ["Alice", "Engineer"]] // } // } ``` -------------------------------- ### Install and Configure Image Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the image plugin. Supports custom uploader functions for file and URL uploads. ```bash npm i @editorjs/image ``` ```javascript image: { class: ImageTool, config: { endpoints: { byFile: '/api/upload/image', byUrl: '/api/fetch/url' }, additionalRequestHeaders: { 'X-CSRF-Token': 'your-token' }, types: 'image/*', // OR custom uploader: uploader: { uploadByFile(file) { const formData = new FormData(); formData.append('image', file); return fetch('/api/upload', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => ({ success: 1, file: { url: data.url } })); }, uploadByUrl(url) { return fetch('/api/fetch-url', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url }) }) .then(res => res.json()) .then(data => ({ success: 1, file: { url: data.url } })); } } } } ``` -------------------------------- ### Install editorjs-annotation Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the community plugin for adding annotations or notes to content using npm. ```bash npm i editorjs-annotation ``` -------------------------------- ### Install editorjs-change-case Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the community plugin for changing the case of text content using npm. ```bash npm i editorjs-change-case ``` -------------------------------- ### Install and Configure Quote Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Quote tool using npm. Configure with inline toolbar and placeholders for quote text and author caption. ```bash npm i @editorjs/quote ``` ```javascript import Quote from '@editorjs/quote'; const editor = new EditorJS({ tools: { quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote author' } } } }); // Output: { "type": "quote", "data": { "text": "...", "caption": "Author", "alignment": "left" } } ``` -------------------------------- ### Install and Configure Checklist Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Install the Checklist tool using npm. Enable inline toolbar for interactive checkbox lists. ```bash npm i @editorjs/checklist ``` ```javascript import Checklist from '@editorjs/checklist'; const editor = new EditorJS({ tools: { checklist: { class: Checklist, inlineToolbar: true } } }); // Output: // { // "type": "checklist", // "data": { // "items": [ // { "text": "Buy groceries", "checked": true }, // { "text": "Clean house", "checked": false } // ] // } // } ``` -------------------------------- ### Install editorjs-paragraph-with-alignment Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Install the community plugin for paragraph blocks with alignment support using npm. ```bash npm i editorjs-paragraph-with-alignment ``` -------------------------------- ### Editor.js Selection Guide Source: https://github.com/schema31/editor-js-ai-skill/blob/main/README.md A reference guide for selecting the appropriate Editor.js configuration or tool implementation based on development needs. ```text Working with Editor.js and need... Basic setup and config → Installation & Configuration Adding content blocks → Official Block Tools (Header, List, Table, Image, etc.) Text formatting → Inline Tools (Bold, Marker, Underline, etc.) Block-level options → Block Tunes (alignment, delete, move) Building your own block → Tools API — Custom Block Tool Building your own inline format → Tools API — Custom Inline Tool Read-only display → Read-Only Mode Multi-language support → i18n Rendering JSON as HTML → Server-Side Rendering (JS, PHP, Python) Framework integration → React, Vue 3, Vanilla JS examples TypeScript types → TypeScript Support ``` -------------------------------- ### Initialize Editor.js (Full Configuration) Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure a comprehensive Editor.js instance with various tools, inline toolbars, tunes, and event handlers. This setup allows for advanced customization and functionality. ```javascript import EditorJS from '@editorjs/editorjs'; import Header from '@editorjs/header'; import List from '@editorjs/list'; import Checklist from '@editorjs/checklist'; import Quote from '@editorjs/quote'; import Warning from '@editorjs/warning'; import Code from '@editorjs/code'; import Delimiter from '@editorjs/delimiter'; import Table from '@editorjs/table'; import ImageTool from '@editorjs/image'; import Embed from '@editorjs/embed'; import Marker from '@editorjs/marker'; import Underline from '@editorjs/underline'; import InlineCode from '@editorjs/inline-code'; const editor = new EditorJS({ holder: 'editorjs', placeholder: 'Start writing your story...', autofocus: true, logLevel: 'ERROR', defaultBlock: 'paragraph', inlineToolbar: ['link', 'marker', 'bold', 'italic'], tunes: ['alignmentTune'], tools: { header: { class: Header, inlineToolbar: true, config: { placeholder: 'Enter a heading', levels: [1, 2, 3, 4], defaultLevel: 2 }, shortcut: 'CMD+SHIFT+H' }, list: { class: List, inlineToolbar: true, config: { defaultStyle: 'unordered' } }, checklist: { class: Checklist, inlineToolbar: true }, quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote author' } }, warning: { class: Warning, inlineToolbar: true, config: { titlePlaceholder: 'Title', messagePlaceholder: 'Message' } }, code: { class: Code }, delimiter: Delimiter, table: { class: Table, inlineToolbar: true, config: { rows: 2, cols: 3 } }, image: { class: ImageTool, config: { endpoints: { byFile: '/api/upload/image', byUrl: '/api/fetch/url' } } }, embed: { class: Embed, config: { services: { youtube: true, vimeo: true, codepen: true, github: true } } }, marker: { class: Marker, shortcut: 'CMD+SHIFT+M' }, underline: { class: Underline, shortcut: 'CMD+U' }, inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' } }, data: {}, onReady: () => { console.log('Editor.js is ready!'); }, onChange: (api, event) => { console.log('Content changed:', event); }, readOnly: false, i18n: { messages: {} } }); ``` -------------------------------- ### Claude Code Plugin Installation Source: https://github.com/schema31/editor-js-ai-skill/blob/main/README.md Commands to register and install the Editor.js skill within the Claude Code environment. ```bash /plugin marketplace add Schema31/Editor-js-ai-skill ``` ```bash /plugin install editorjs-skills@editorjs-skills ``` -------------------------------- ### Initialize Editor.js (Minimal) Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Create a basic Editor.js instance by specifying the holder element ID. This setup is suitable for simple use cases. ```javascript const editor = new EditorJS({ holder: 'editorjs' }); ``` -------------------------------- ### Configuring Editor.js Plugins Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Examples of how to configure various community plugins such as alignment, color, and annotation tools. ```APIDOC ## Plugin Configuration ### Alignment Tune - **Config**: `default` (string), `blocks` (object mapping block types to alignment). ### Text Color Plugin - **Config**: - `colorCollections` (array): List of available colors. - `defaultColor` (string): Default color hex code. - `type` (string): 'text' or 'marker'. - `customPicker` (boolean): Enable custom color selection. ### Hyperlink Plugin - **Config**: - `shortcut` (string): Trigger key combination. - `target` (string): Link target attribute. - `rel` (string): Link relationship attribute. - `availableTargets` (array): Allowed target values. - `availableRels` (array): Allowed rel values. ``` -------------------------------- ### Custom Tool: Inline Tool Example Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Provides a comprehensive example of creating a custom inline tool in Editor.js, including its rendering, state management, and surrounding/unwrapping logic. ```APIDOC ## Tools API — Creating a Custom Inline Tool This section details the creation of a custom inline tool. It covers defining the tool's properties, its rendering logic, how it interacts with the editor's selection, and its state management. ### Inline Tool Properties - `isInline`: Must return `true` for inline tools. - `sanitize`: Defines allowed HTML attributes for the tool's tag. - `tag`: The HTML tag to be used for the inline tool (e.g., 'SPAN'). - `class`: CSS class applied to the tool's element. - `shortcut`: Keyboard shortcut for activating the tool. ### Inline Tool Methods - `render()`: Renders the tool's button for the inline toolbar. - `surround(range)`: Wraps the selected content with the tool's tag or unwraps it if already applied. - `wrap(range)`: Creates the HTML element and inserts it around the selected content. - `unwrap(range)`: Removes the tool's HTML element and restores the original content. - `checkState()`: Updates the tool's `state` based on the current selection. ### State Management - `state` (getter/setter): Manages the active state of the inline tool, toggling the active class on its button. ```javascript class MyInlineTool { static get isInline() { return true; } static get sanitize() { return { span: { class: 'my-custom-style' } }; } get state() { return this._state; } set state(state) { this._state = state; this.button.classList.toggle(this.api.styles.inlineToolButtonActive, state); } constructor({ api }) { this.api = api; this._state = false; this.tag = 'SPAN'; this.class = 'my-custom-style'; } render() { this.button = document.createElement('button'); this.button.type = 'button'; this.button.innerHTML = '...'; this.button.classList.add(this.api.styles.inlineToolButton); return this.button; } surround(range) { if (this.state) { this.unwrap(range); } else { this.wrap(range); } } wrap(range) { const selectedText = range.extractContents(); const span = document.createElement(this.tag); span.classList.add(this.class); span.appendChild(selectedText); range.insertNode(span); this.api.selection.expandToTag(span); } unwrap(range) { const span = this.api.selection.findParentTag(this.tag, this.class); const text = range.extractContents(); span.remove(); range.insertNode(text); } checkState() { const span = this.api.selection.findParentTag(this.tag, this.class); this.state = !!span; } static get shortcut() { return 'CMD+SHIFT+S'; } } ``` ``` -------------------------------- ### Repository Structure Source: https://github.com/schema31/editor-js-ai-skill/blob/main/README.md The directory layout of the Editor.js AI skill repository, highlighting configuration and example files. ```text ├── README.md ├── context7.json # Context7 configuration ├── .claude-plugin/ │ └── marketplace.json # Claude Code plugin registration └── skills/ └── editorjs/ ├── SKILL.md # Main skill documentation └── examples/ ├── basic-setup.js # Minimal and full configuration ├── custom-block-tool.js # Complete custom block tool example ├── custom-inline-tool.js # Complete custom inline tool example └── server-rendering.js # JSON-to-HTML rendering (Node.js) ``` -------------------------------- ### Configure Full Editor.js Instance Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Set up a comprehensive editor instance with custom tools, configuration options, pre-loaded data, and event callbacks. ```javascript import EditorJS from '@editorjs/editorjs'; import Header from '@editorjs/header'; import List from '@editorjs/list'; import Checklist from '@editorjs/checklist'; import Quote from '@editorjs/quote'; import Warning from '@editorjs/warning'; import Code from '@editorjs/code'; import Delimiter from '@editorjs/delimiter'; import Table from '@editorjs/table'; import ImageTool from '@editorjs/image'; import Embed from '@editorjs/embed'; import Marker from '@editorjs/marker'; import Underline from '@editorjs/underline'; import InlineCode from '@editorjs/inline-code'; const editor = new EditorJS({ holder: 'editorjs', placeholder: 'Start writing your article...', autofocus: true, logLevel: 'ERROR', defaultBlock: 'paragraph', inlineToolbar: ['link', 'marker', 'bold', 'italic', 'underline', 'inlineCode'], tools: { header: { class: Header, inlineToolbar: true, config: { placeholder: 'Enter a heading', levels: [1, 2, 3, 4], defaultLevel: 2 }, shortcut: 'CMD+SHIFT+H' }, list: { class: List, inlineToolbar: true, config: { defaultStyle: 'unordered' } }, checklist: { class: Checklist, inlineToolbar: true }, quote: { class: Quote, inlineToolbar: true, config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote author' } }, warning: { class: Warning, inlineToolbar: true, config: { titlePlaceholder: 'Title', messagePlaceholder: 'Message' } }, code: { class: Code }, delimiter: Delimiter, table: { class: Table, inlineToolbar: true, config: { rows: 2, cols: 3, withHeadings: true } }, image: { class: ImageTool, config: { endpoints: { byFile: '/api/upload/image', byUrl: '/api/fetch/url' } } }, embed: { class: Embed, config: { services: { youtube: true, vimeo: true, codepen: true } } }, marker: { class: Marker, shortcut: 'CMD+SHIFT+M' }, underline: { class: Underline, shortcut: 'CMD+U' }, inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' } }, data: { time: Date.now(), blocks: [ { type: 'header', data: { text: 'Welcome to Editor.js', level: 2 } }, { type: 'paragraph', data: { text: 'This is pre-loaded content.' } } ] }, onReady: () => { console.log('Editor.js is ready!'); }, onChange: (api, event) => { console.log('Content changed:', event.type); } }); ``` -------------------------------- ### Configure Warning Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Configure the Warning tool with custom placeholders for title and message. ```javascript import Warning from '@editorjs/warning'; const editor = new EditorJS({ tools: { warning: { class: Warning, inlineToolbar: true, config: { titlePlaceholder: 'Title', messagePlaceholder: 'Message' } } } }); // Output: { "type": "warning", "data": { "title": "Caution", "message": "Irreversible action." } } ``` -------------------------------- ### Configure Block Tunes Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Initialize Editor.js with alignment tunes applied to specific tools or globally. ```javascript import AlignmentTune from 'editorjs-text-alignment-blocktune'; import Header from '@editorjs/header'; import Paragraph from '@editorjs/paragraph'; const editor = new EditorJS({ tools: { alignmentTune: { class: AlignmentTune, config: { default: 'left', blocks: { header: 'center', list: 'left' } } }, // Apply tune to specific tools header: { class: Header, tunes: ['alignmentTune'] }, paragraph: { class: Paragraph, tunes: ['alignmentTune'] } }, // OR apply to ALL blocks globally: tunes: ['alignmentTune'] }); ``` -------------------------------- ### Check Editor Ready State with Promise Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Use the `isReady` property with a Promise to execute code once the editor is fully initialized. Handles potential initialization failures. ```javascript // Promise editor.isReady .then(() => console.log('Ready!')) .catch((reason) => console.log(`Failed: ${reason}`)); ``` -------------------------------- ### Configure Read-Only Mode Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Enable read-only mode during initialization or toggle it at runtime. Tools must support read-only mode via a static getter. ```javascript // Initialize in read-only const editor = new EditorJS({ readOnly: true, tools: { /* ... */ }, data: savedData }); // Toggle at runtime await editor.readOnly.toggle(); // Check state const isReadOnly = editor.readOnly.isEnabled; ``` -------------------------------- ### Check Editor Ready State with async/await Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Use `async/await` with the `isReady` property for a more synchronous-looking way to wait for editor initialization. Ensure the surrounding function is `async`. ```javascript // async/await await editor.isReady; ``` -------------------------------- ### Apply Custom Tunes Per Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Specify which custom tunes should be available for individual tools by listing them in the tool's 'tunes' property. ```javascript tools: { header: { class: Header, tunes: ['alignmentTune'] }, paragraph: { class: Paragraph, tunes: ['alignmentTune'] } } ``` -------------------------------- ### Create a Custom Inline Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Implement the Inline Tool interface to handle text selection formatting. Ensure the class includes render, surround, and state management methods. ```javascript class MyInlineTool { static get isInline() { return true; } static get sanitize() { return { span: { class: 'my-custom-style' } }; } get state() { return this._state; } set state(state) { this._state = state; this.button.classList.toggle(this.api.styles.inlineToolButtonActive, state); } constructor({ api }) { this.api = api; this._state = false; this.tag = 'SPAN'; this.class = 'my-custom-style'; } render() { this.button = document.createElement('button'); this.button.type = 'button'; this.button.innerHTML = '...'; this.button.classList.add(this.api.styles.inlineToolButton); return this.button; } surround(range) { if (this.state) { this.unwrap(range); } else { this.wrap(range); } } wrap(range) { const selectedText = range.extractContents(); const span = document.createElement(this.tag); span.classList.add(this.class); span.appendChild(selectedText); range.insertNode(span); this.api.selection.expandToTag(span); } unwrap(range) { const span = this.api.selection.findParentTag(this.tag, this.class); const text = range.extractContents(); span.remove(); range.insertNode(text); } checkState() { const span = this.api.selection.findParentTag(this.tag, this.class); this.state = !!span; } static get shortcut() { return 'CMD+SHIFT+S'; } } ``` -------------------------------- ### Configure Inline Tools Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Register inline tools and define their keyboard shortcuts and toolbar visibility. ```javascript import Marker from '@editorjs/marker'; import Underline from '@editorjs/underline'; import InlineCode from '@editorjs/inline-code'; const editor = new EditorJS({ tools: { marker: { class: Marker, shortcut: 'CMD+SHIFT+M' }, underline: { class: Underline, shortcut: 'CMD+U' }, inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' } }, inlineToolbar: ['bold', 'italic', 'link', 'marker', 'underline', 'inlineCode'] }); // Marker wraps text in: highlighted text // Underline wraps text in: underlined text // Inline Code wraps text in: code ``` -------------------------------- ### Configure Checklist Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the Checklist tool with inline toolbar support. Requires `@editorjs/checklist` package. ```bash npm i @editorjs/checklist ``` ```javascript checklist: { class: Checklist, inlineToolbar: true } ``` -------------------------------- ### Configure Annotation Plugin Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the Annotation plugin with a placeholder text and an option to include links. ```javascript annotation: { class: Annotation, config: { placeholder: 'Add a note', withLink: true } } ``` -------------------------------- ### Configure Embed Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Configure the Embed tool to support various services, including custom service definitions. ```javascript import Embed from '@editorjs/embed'; const editor = new EditorJS({ tools: { embed: { class: Embed, config: { services: { youtube: true, vimeo: true, codepen: true, github: true, twitter: true, // Custom service myService: { regex: /https?:\/\/mysite\.com\/embed\/(.+)/, embedUrl: 'https://mysite.com/embed/<%= remote_id %>', html: '', height: 300, width: 600 } } } } } }); // Output: // { // "type": "embed", // "data": { // "service": "youtube", // "source": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", // "embed": "https://www.youtube.com/embed/dQw4w9WgXcQ", // "width": 580, "height": 320, "caption": "" // } // } ``` -------------------------------- ### Configure Image Tool Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Configure the Image tool with endpoints or a custom uploader for handling image files and URLs. ```javascript import ImageTool from '@editorjs/image'; const editor = new EditorJS({ tools: { image: { class: ImageTool, config: { endpoints: { byFile: '/api/upload/image', byUrl: '/api/fetch/url' }, // OR custom uploader: uploader: { uploadByFile(file) { const formData = new FormData(); formData.append('image', file); return fetch('/api/upload', { method: 'POST', body: formData }) .then(res => res.json()) .then(data => ({ success: 1, file: { url: data.url } })); }, uploadByUrl(url) { return fetch('/api/fetch-url', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url }) }) .then(res => res.json()) .then(data => ({ success: 1, file: { url: data.url } })); } } } } } }); // Output: // { // "type": "image", // "data": { // "file": { "url": "https://example.com/image.jpg" }, // "caption": "Image caption", // "withBorder": false, "stretched": false, "withBackground": false // } // } ``` -------------------------------- ### Editor.js Configuration with TypeScript Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Basic Editor.js configuration using TypeScript, including defining tools and their properties. Requires importing necessary types from '@editorjs/editorjs'. ```typescript import EditorJS, { EditorConfig, OutputData, BlockToolConstructable, InlineToolConstructable, API, BlockAPI, ToolConfig, LogLevels } from '@editorjs/editorjs'; const config: EditorConfig = { holder: 'editorjs', tools: { header: { class: Header as unknown as BlockToolConstructable, config: { levels: [1, 2, 3], defaultLevel: 2 } } } }; const editor = new EditorJS(config); editor.save().then((data: OutputData) => { data.blocks.forEach(block => console.log(block.type, block.data)); }); ``` -------------------------------- ### Configure Hyperlink Plugin Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the Hyperlink plugin with a keyboard shortcut, target attribute, rel attribute, and lists of available targets and rels. ```javascript hyperlink: { class: Hyperlink, config: { shortcut: 'CMD+L', target: '_blank', rel: 'nofollow', availableTargets: ['_blank', '_self'], availableRels: ['nofollow', 'noreferrer'] } } ``` -------------------------------- ### Configure List Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the List tool with inline toolbar and a default style (ordered or unordered). Requires `@editorjs/list` package. ```bash npm i @editorjs/list ``` ```javascript list: { class: List, inlineToolbar: true, config: { defaultStyle: 'unordered' } } ``` -------------------------------- ### Define Multiple Toolbox Entries Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Return an array of objects in the static toolbox getter to provide multiple tool variations. ```javascript class HeadingTool { static get toolbox() { return [ { icon: '...', title: 'Heading 1', data: { level: 1 } }, { icon: '...', title: 'Heading 2', data: { level: 2 } }, { icon: '...', title: 'Heading 3', data: { level: 3 } } ]; } } ``` -------------------------------- ### Block Tunes Configuration Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Configure block-level settings like text alignment within the Editor.js instance. ```APIDOC ## Block Tunes Configuration ### Description Configure block-level settings like text alignment that appear in the block's settings menu. ### Implementation ```javascript import AlignmentTune from 'editorjs-text-alignment-blocktune'; const editor = new EditorJS({ tools: { alignmentTune: { class: AlignmentTune, config: { default: 'left', blocks: { header: 'center', list: 'left' } } }, header: { class: Header, tunes: ['alignmentTune'] } }, tunes: ['alignmentTune'] }); ``` ``` -------------------------------- ### Configure Code and Delimiter Tools Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Register the Code and Delimiter tools in the EditorJS configuration. ```javascript import Code from '@editorjs/code'; import Delimiter from '@editorjs/delimiter'; const editor = new EditorJS({ tools: { code: { class: Code }, delimiter: Delimiter } }); // Code output: { "type": "code", "data": { "code": "const x = 42;" } } // Delimiter output: { "type": "delimiter", "data": {} } ``` -------------------------------- ### Minimal Block Tool Implementation Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md A basic structure for a custom Editor.js block tool, including constructor, static toolbox getter, render method, save method, and validation. ```javascript class MyTool { constructor({ data, api, config, readOnly, block }) { this.data = data || {}; this.api = api; this.config = config; this.readOnly = readOnly; } static get toolbox() { return { icon: '...', title: 'My Tool' }; } render() { this.wrapper = document.createElement('div'); this.wrapper.classList.add('my-tool'); this.wrapper.contentEditable = !this.readOnly; this.wrapper.innerHTML = this.data.text || ''; return this.wrapper; } save(blockContent) { return { text: blockContent.innerHTML }; } validate(savedData) { return savedData.text.trim() !== ''; } static get isReadOnlySupported() { return true; } } ``` -------------------------------- ### Configure Text Color Plugin Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the ColorPlugin to define available colors, default color, type (text or marker), and enable a custom color picker. ```javascript color: { class: ColorPlugin, config: { colorCollections: ['#000000', '#D0021B', '#F5A623', '#4A90E2', '#7ED321'], defaultColor: '#000000', type: 'text', // 'text' for text color, 'marker' for background customPicker: true } } ``` -------------------------------- ### Optional Block Tool Methods and Static Getters Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Demonstrates optional methods and static getters for enhancing custom Editor.js block tools, including rendering settings, merging, sanitization, conversion, shortcuts, and paste handling. ```javascript class MyTool { renderSettings() { return [ { icon: '...', label: 'With border', toggle: 'withBorder', isActive: this.data.withBorder, onActivate: () => { this.data.withBorder = !this.data.withBorder; this.wrapper.classList.toggle('with-border'); } } ]; } merge(data) { this.data.text += data.text; this.wrapper.innerHTML = this.data.text; } destroy() { // Remove event listeners, clear cache } static get sanitize() { return { text: { b: true, i: true, a: { href: true, target: '_blank' } } }; } static get conversionConfig() { return { export: 'text', import: 'text' }; } // Function-based conversion (for complex data) static get conversionConfig() { return { export: (data) => data.items.join('. '), import: (string) => ({ items: string.split('.').map(s => s.trim()).filter(Boolean), style: 'unordered' }) }; } static get shortcut() { return 'CMD+SHIFT+M'; } static get enableLineBreaks() { return false; } static get pasteConfig() { return { tags: ['IMG'], files: { mimeTypes: ['image/*'], extensions: ['gif', 'jpg', 'png', 'webp'] }, patterns: { image: /https?: //S+\.(gif|jpe?g|tiff|png|webp)$/i } }; } onPaste(event) { switch (event.type) { case 'tag': { const element = event.detail.data; this.data = { url: element.src }; break; } case 'pattern': { this.data = { url: event.detail.data }; break; } case 'file': { const reader = new FileReader(); reader.onload = (e) => { this.data = { url: e.target.result }; }; reader.readAsDataURL(event.detail.file); break; } } } } ``` -------------------------------- ### Configure Header Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the Header tool with options for inline toolbar, placeholder text, heading levels, and default level. Requires `@editorjs/header` package. ```bash npm i @editorjs/header ``` ```javascript header: { class: Header, inlineToolbar: true, config: { placeholder: 'Enter a heading', levels: [1, 2, 3, 4, 5, 6], defaultLevel: 2 } } ``` -------------------------------- ### Apply Custom Tunes Globally Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure Editor.js to apply custom tunes to all blocks by specifying them in the main 'tunes' array. ```javascript import AlignmentTune from 'editorjs-text-alignment-blocktune'; const editor = new EditorJS({ tools: { alignmentTune: { class: AlignmentTune, config: { default: 'left', blocks: { header: 'center', list: 'left' } } } }, tunes: ['alignmentTune'] // Apply to ALL blocks }); ``` -------------------------------- ### Register Custom AlertBox Tool with EditorJS Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Initialize the Editor.js instance and register the custom 'AlertBox' block tool. This configuration sets up the editor holder, defines the tools available, and configures the custom tool with inline toolbar support and default settings. ```javascript // Register the custom tool const editor = new EditorJS({ holder: 'editorjs', tools: { alertBox: { class: AlertBox, inlineToolbar: true, config: { defaultType: 'info', placeholder: 'Type your alert message...' } } } }); ``` -------------------------------- ### Configure Alignment Tune Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the AlignmentTuneTool with default alignment and specific block type alignments. ```javascript alignmentTune: { class: AlignmentTuneTool, config: { default: 'left', blocks: { header: 'center' } } } ``` -------------------------------- ### Configure Internationalization (i18n) Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Provide custom translations for UI elements, tool names, and specific tool configurations via the i18n property. ```javascript const editor = new EditorJS({ i18n: { messages: { ui: { "blockTunes": { "toggler": { "Click to tune": "Click to tune", "or drag to move": "or drag to move" } }, "inlineToolbar": { "converter": { "Convert to": "Convert to" } }, "toolbar": { "toolbox": { "Add": "Add" } }, "popover": { "Filter": "Filter", "Nothing found": "Nothing found" } }, toolNames: { "Text": "Text", "Heading": "Heading", "List": "List", "Checklist": "Checklist", "Quote": "Quote", "Warning": "Warning", "Code": "Code", "Delimiter": "Delimiter", "Table": "Table", "Image": "Image", "Marker": "Marker", "Bold": "Bold", "Italic": "Italic", "Link": "Link", "Underline": "Underline", "InlineCode": "Inline Code" }, tools: { "header": { "Heading 1": "Heading 1", "Heading 2": "Heading 2" }, "list": { "Ordered": "Ordered", "Unordered": "Unordered" }, "table": { "Add column to left": "Add column to left", "Add column to right": "Add column to right", "Delete column": "Delete column", "Add row above": "Add row above", "Add row below": "Add row below", "Delete row": "Delete row", "With headings": "With headings", "Without headings": "Without headings" } }, blockTunes: { "delete": { "Delete": "Delete", "Click to delete": "Click to delete" }, "moveUp": { "Move up": "Move up" }, "moveDown": { "Move down": "Move down" } } } } }); ``` -------------------------------- ### Manage Read-Only Mode Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Initialize the editor in read-only mode and toggle it at runtime. ```javascript import EditorJS from '@editorjs/editorjs'; import Header from '@editorjs/header'; import List from '@editorjs/list'; // Initialize in read-only mode const editor = new EditorJS({ holder: 'editorjs-readonly', readOnly: true, tools: { header: { class: Header }, list: { class: List } }, data: { blocks: [ { type: 'header', data: { text: 'Read-only article', level: 1 } }, { type: 'paragraph', data: { text: 'This content cannot be edited.' } } ] } }); // Toggle read-only at runtime async function toggleReadOnly() { await editor.readOnly.toggle(); console.log('Read-only:', editor.readOnly.isEnabled); } // Check current state const isReadOnly = editor.readOnly.isEnabled; ``` -------------------------------- ### Configure Paragraph Tool Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Configure the Paragraph tool with inline toolbar support and options to preserve blank lines. Requires `@editorjs/paragraph` package. ```bash npm i @editorjs/paragraph ``` ```javascript paragraph: { class: Paragraph, inlineToolbar: true, config: { placeholder: 'Start typing...', preserveBlank: true } } ``` -------------------------------- ### Integrate Editor.js with React Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md Uses useRef to manage the editor instance and useEffect to handle initialization and cleanup. ```jsx import { useEffect, useRef } from 'react'; import EditorJS from '@editorjs/editorjs'; import Header from '@editorjs/header'; import List from '@editorjs/list'; function EditorComponent({ data, onChange }) { const editorRef = useRef(null); const instanceRef = useRef(null); useEffect(() => { if (!instanceRef.current) { instanceRef.current = new EditorJS({ holder: editorRef.current, tools: { header: Header, list: List }, data: data || {}, onChange: async (api) => { const savedData = await api.saver.save(); onChange?.(savedData); } }); } return () => { instanceRef.current?.destroy(); instanceRef.current = null; }; }, []); return
; } ``` -------------------------------- ### Use Editor API Methods Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt Perform programmatic operations on blocks, caret positioning, selection, and data lifecycle management. ```javascript const editor = new EditorJS({ holder: 'editorjs', tools: { /* ... */ } }); // Wait for ready state await editor.isReady; // === Blocks API === // Insert a new block editor.blocks.insert('header', { text: 'New heading', level: 2 }); editor.blocks.insert('paragraph', { text: 'Hello' }, {}, 3); // at index 3 // Manipulate blocks editor.blocks.delete(0); editor.blocks.move(toIndex, fromIndex); const block = editor.blocks.getBlockByIndex(0); const count = editor.blocks.getBlocksCount(); const index = editor.blocks.getCurrentBlockIndex(); // Render new content await editor.blocks.render({ blocks: [ { type: 'header', data: { text: 'Fresh content', level: 1 } } ] }); // Clear all blocks editor.blocks.clear(); // === Caret API === editor.caret.setToBlock(index, 'end'); // 'start' | 'end' | 'default' editor.caret.focus(true); // true = focus at the end // === Selection API === editor.selection.expandToBlock(); const mark = editor.selection.findParentTag('MARK'); // === Save & Destroy === const data = await editor.save(); editor.destroy(); // Clean up when removing editor from page ```