### Setup and Development Commands Source: https://github.com/yeole-rohan/ray-editor/blob/main/README.md Commands to clone the repository, install dependencies, run the watch build, execute tests, run e2e tests, and build a specific wrapper package. Requires Node ≥ 20. ```bash git clone https://github.com/yeole-rohan/ray-editor npm install # installs the core package + all packages/* workspaces npm run dev # watch build (core) npm test # run tests (vitest + jsdom) npm run test:e2e:chrome # Playwright e2e npm run build --workspace=packages/react # build a specific wrapper (react/vue/angular/svelte) ``` -------------------------------- ### Install @rohanyeole/ray-editor-angular Source: https://github.com/yeole-rohan/ray-editor/blob/main/packages/angular/README.md Install the required packages using npm. ```bash npm install @rohanyeole/ray-editor @rohanyeole/ray-editor-angular ``` -------------------------------- ### Install @ckeditor/ckeditor5-build-classic Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-npm.html Command to install the CKEditor 5 classic build. ```bash npm install @ckeditor/ckeditor5-build-classic ``` -------------------------------- ### Install @rohanyeole/ray-editor-react Source: https://github.com/yeole-rohan/ray-editor/blob/main/packages/react/README.md Install the required editor core and the React wrapper package. ```bash npm install @rohanyeole/ray-editor @rohanyeole/ray-editor-react ``` -------------------------------- ### Install RayEditor Svelte wrapper and core package via npm Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/svelte-wysiwyg-editor.html Install the official Svelte wrapper and the core RayEditor package. This is the prerequisite for all other examples on the page. ```bash npm install @rohanyeole/ray-editor-svelte @rohanyeole/ray-editor ``` -------------------------------- ### Install tinymce Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-npm.html Command to install TinyMCE and its official React wrapper. ```bash npm install tinymce @tinymce/tinymce-react ``` -------------------------------- ### Install @rohanyeole/ray-editor and framework wrappers Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-npm.html Commands to install the core package and its official wrappers for React, Vue 3, Angular, and Svelte. ```bash npm install @rohanyeole/ray-editor # React wrapper npm install @rohanyeole/ray-editor-react # Vue 3 wrapper npm install @rohanyeole/ray-editor-vue # Angular wrapper npm install @rohanyeole/ray-editor-angular # Svelte wrapper npm install @rohanyeole/ray-editor-svelte ``` -------------------------------- ### Install Ray Editor with pnpm Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Install the Ray Editor package using pnpm. ```bash pnpm add @rohanyeole/ray-editor ``` -------------------------------- ### Install Ray Editor Dependencies Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/react-blog-editor-markdown.html Install the required packages for the React blog editor: @rohanyeole/ray-editor-react and @rohanyeole/ray-editor. ```bash npm install @rohanyeole/ray-editor-react @rohanyeole/ray-editor ``` -------------------------------- ### Install Ray Editor with yarn Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Install the Ray Editor package using yarn. ```bash yarn add @rohanyeole/ray-editor ``` -------------------------------- ### Install CKEditor 5 React and Classic build Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-ckeditor.html Install the CKEditor 5 React wrapper and the Classic build via npm. ```bash npm install @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic ``` -------------------------------- ### Install trix Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-npm.html Command to install the Trix editor package. ```bash npm install trix ``` -------------------------------- ### Install quill Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-npm.html Command to install the Quill editor package. ```bash npm install quill ``` -------------------------------- ### Install RayEditor via npm Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-froala.html Install the RayEditor package from npm. This is the first step to using RayEditor in your project. ```bash npm install @rohanyeole/ray-editor ``` -------------------------------- ### Install TinyMCE via npm Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-tinymce.html Install TinyMCE and its React wrapper. You must also self-host or configure a CDN API key. ```bash npm install tinymce @tinymce/tinymce-react # You also need to self-host or configure a CDN API key ``` -------------------------------- ### Method: editor.use(plugin) Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Documentation for the editor.use method used to install plugins after construction. ```APIDOC ## [METHOD] editor.use(plugin) ### Description Installs a plugin into the editor after construction. The plugin's `install` method is called with the editor instance. ### Method `use` ### Parameters - **plugin** (RayPlugin) - Required - The plugin object to install. Must have a `name` and an `install(editor)` method. ### Example ```typescript const myPlugin: RayPlugin = { name: 'my-plugin', version: '1.0.0', install(editor) { // ... }, destroy() { // ... }, }; editor.use(myPlugin); ``` ``` -------------------------------- ### Initialize RayEditor with options in main.ts Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Imports RayEditor and its CSS, then creates a new editor instance on the 'my-editor' element. Options include theme, word count, slash commands, markdown shortcuts, a toolbar layout, and an onChange callback. The example also shows setContent and getContent usage. ```typescript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/css'; const editor = new RayEditor('my-editor', { theme: 'light', // 'light' | 'dark' | 'auto' wordCount: true, // show live word count bar slashCommands: true, // / command palette markdownShortcuts: true, // ## → H2, **text** → bold toolbar: [ ['bold', 'italic', 'underline', 'highlight'], ['headings', 'blockquote', 'callout'], ['orderedList', 'unorderedList', 'taskList'], ['codeBlock', 'link', 'table'], ['undo', 'redo', 'removeFormat'], ], onChange: (html) => console.log('changed', html), }); editor.setContent('

Hello world!

'); const html = editor.getContent(); // clean HTML string ``` -------------------------------- ### Create a Ray Editor plugin (my-plugin.ts) Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Defines a plugin object with name, version, install, and destroy methods. The install method listens to content:change events and registers a custom slash command. The plugin is installed at construction time via the plugins option or after construction via editor.use(). ```typescript import type { RayPlugin } from '@rohanyeole/ray-editor'; const myPlugin: RayPlugin = { name: 'my-plugin', version: '1.0.0', install(editor) { // Listen to content changes editor.on('content:change', (html) => { console.log('changed:', html.length, 'chars'); }); // Register a custom slash command editor.registerSlashCommand({ name: 'Timestamp', icon: '🕐', description: 'Insert current timestamp', action: () => document.execCommand('insertText', false, new Date().toISOString()), }); }, destroy() { // Cleanup — called by editor.destroy() }, }; // Install at construction time: const editor = new RayEditor('editor', { plugins: [myPlugin] }); // Or after construction: editor.use(myPlugin); ``` -------------------------------- ### Install RayEditor Vue wrapper and core package Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/vue-wysiwyg-editor.html Install the official Vue 3 wrapper and the core editor package via npm. Both packages are required for Vue integration. ```bash npm install @rohanyeole/ray-editor-vue @rohanyeole/ray-editor ``` -------------------------------- ### Install RayEditor Angular packages Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/angular-wysiwyg-editor.html Install the RayEditor Angular wrapper and core editor package via npm. Required before using the component in an Angular project. ```bash npm install @rohanyeole/ray-editor-angular @rohanyeole/ray-editor ``` -------------------------------- ### Dark mode configuration Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/vue-wysiwyg-editor.html Set darkMode to 'auto' to follow the OS preference. This is a standalone configuration example. ```javascript const editorOptions = { darkMode: 'auto' }; // follows OS preference ``` -------------------------------- ### Initialize RayEditor with options Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-ckeditor.html Import RayEditor and its CSS, then create a new instance with a selector and options like theme, placeholder, and onChange callback. ```javascript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/dist/ray-editor.css'; const editor = new RayEditor('#editor', { theme: 'auto', // respects system dark/light mode placeholder: 'Write something...', onChange: (html) => console.log(html), }); ``` -------------------------------- ### Initialize RayEditor with toolbar and theme, and log content changes Source: https://github.com/yeole-rohan/ray-editor/blob/main/tests/e2e/paste-html/vscode.html Creates a new RayEditor instance on the 'container' element with a toolbar of bold, italic, and link actions and a dark theme. Attaches a 'content:change' event listener that logs the updated HTML to the console. ```javascript const editor = new RayEditor('container', { toolbar: ['bold', 'italic', 'link'], theme: 'dark', }); editor.on('content:change', ({ html }) => { console.log(html); }); ``` -------------------------------- ### Initialize RayEditor instance Source: https://github.com/yeole-rohan/ray-editor/blob/main/tests/e2e/paste-html/notion.html Create a new editor instance by specifying the container ID and configuration options, then listen for content changes. ```javascript const editor = new RayEditor('container', { toolbar: ['bold', 'italic', 'link'], theme: 'dark', }); editor.on('content:change', ({ html }) => { console.log(html); }); ``` -------------------------------- ### Initialize RayEditor with JavaScript Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-froala.html Import RayEditor and its CSS, then create a new editor instance on a DOM element. Configure placeholder text and toolbar options. ```javascript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/dist/ray-editor.css'; const editor = new RayEditor(document.getElementById('editor'), { placeholder: 'Start typing...', toolbar: ['bold','italic','underline','link','table','imageUpload'] }); ``` -------------------------------- ### Reactive Forms integration Source: https://github.com/yeole-rohan/ray-editor/blob/main/packages/angular/README.md Example of using the RayEditorAngularComponent within an Angular Reactive Form. ```typescript import { FormBuilder } from '@angular/forms'; @Component({ template: `
`, }) export class FormComponent { form = this.fb.group({ body: [''] }); constructor(private fb: FormBuilder) {} } ``` -------------------------------- ### Standalone component usage Source: https://github.com/yeole-rohan/ray-editor/blob/main/packages/angular/README.md Example of using the RayEditorAngularComponent in an Angular 15+ standalone component. ```typescript import { Component } from '@angular/core'; import { RayEditorAngularComponent } from '@rohanyeole/ray-editor-angular'; @Component({ selector: 'app-root', standalone: true, imports: [RayEditorAngularComponent], template: `
{{ content }}
`, }) export class AppComponent { content = '

Hello world

'; editorOptions = { theme: 'light' as const, wordCount: true, toolbar: [ ['bold', 'italic', 'underline'], ['headings', 'blockquote'], ['link', 'imageUpload'], ], }; } ``` -------------------------------- ### Constructor: new RayEditor(element, options) Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Documentation for the RayEditor constructor. ```APIDOC ## [CONSTRUCTOR] new RayEditor(element, options) ### Description Creates a new RayEditor instance attached to the given DOM element. ### Method `new RayEditor` ### Parameters - **element** (string | HTMLElement) - Required - The CSS selector or DOM element to attach the editor to. - **options** (object) - Optional - Configuration options. - **plugins** (RayPlugin[]) - Optional - An array of plugins to install at construction time. - **slashCommands** (boolean) - Optional - When `true`, typing `/` at the start of an empty block opens the command palette. ### Example ```typescript const editor = new RayEditor('editor', { plugins: [myPlugin] }); ``` ``` -------------------------------- ### Import and initialize RayEditor Source: https://github.com/yeole-rohan/ray-editor/blob/main/README.md Import the RayEditor class and its CSS, then create an editor instance bound to the element with id 'editor'. The CSS import is required for the editor to render correctly. ```js import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/css'; const editor = new RayEditor('editor', { theme: 'light' }); ``` -------------------------------- ### Accessing the editor instance with ref Source: https://github.com/yeole-rohan/ray-editor/blob/main/packages/vue/README.md Use a template ref to access the RayEditorVue instance and call its getContent() method, for example in a button click handler. ```vue ``` -------------------------------- ### Basic usage with v-model and options Source: https://github.com/yeole-rohan/ray-editor/blob/main/packages/vue/README.md Use the RayEditorVue component in a Vue 3 script setup, binding content with v-model and passing editor options like theme, word count, and toolbar configuration. ```vue ``` -------------------------------- ### Composition API usage with v-model and editor options Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/vue-wysiwyg-editor.html Use RayEditorVue in a Vue 3 Composition API component with script setup. Import ref, the component, and CSS. Define content as a ref and editorOptions with placeholder, toolbar, and darkMode. ```html ``` -------------------------------- ### Markdown keyboard shortcuts in rich text mode Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/implement-markdown-mode.html Lists the Markdown shortcuts that trigger in rich text mode on a blank line or at the start of text. Includes bold, italic, headings, blockquote, lists, task lists, and fenced code blocks. ```markdown **text** → bold *text* → italic ## space → Heading 2 > space → blockquote - space → unordered list item [ ] space → task list item ``` Enter → fenced code block ``` -------------------------------- ### Initialize RayEditor and Import/Export Markdown Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/markdown-editor-javascript.html Initializes a RayEditor instance with a toolbar that includes markdown toggle, import, and export buttons. Imports a Markdown string and exports the edited content back to Markdown, logging it to the console. ```javascript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/dist/ray-editor.css'; const editor = new RayEditor(document.getElementById('editor'), { toolbar: ['bold', 'italic', 'heading', 'markdownToggle', 'importMarkdown', 'exportMarkdown'] }); // Import existing Markdown content editor.importMarkdown('# Hello World This is **bold** and _italic_ text. - Item 1 - Item 2'); // Export back to Markdown const markdown = editor.exportMarkdown(); console.log(markdown); ``` -------------------------------- ### Use importMarkdown, exportMarkdown, and content:change event Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/implement-markdown-mode.html Shows how to import a Markdown string, export the current content as Markdown, and listen for content changes. The content:change event fires in both rich text and Markdown modes. ```javascript // Import Markdown string directly (e.g. from a CMS API) editor.importMarkdown(` # My Article This is a paragraph with **bold** and _italic_ text. ## Features - Task lists - Tables - Code blocks ```javascript console.log('Hello world'); ``` `); // Export the current content as Markdown const markdown = editor.exportMarkdown(); console.log(markdown); // returns clean Markdown string // Listen for content changes (fires in both modes) editor.on('content:change', ({ html }) => { saveToServer(html); }); ``` -------------------------------- ### Interface: RayPlugin Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Documentation for the RayPlugin interface used to extend the editor. ```APIDOC ## [PLUGIN] RayPlugin ### Description A plugin is a plain object with `name` and `install(editor)` that lets you extend the editor without forking it. ### Properties - **name** (string) - Required - The unique name of the plugin. - **version** (string) - Optional - The plugin version. - **install** (function) - Required - Called with the editor instance when the plugin is installed. Use it to register event listeners, slash commands, etc. - **destroy** (function) - Optional - Called by `editor.destroy()` for cleanup. ### Example ```typescript import type { RayPlugin } from '@rohanyeole/ray-editor'; const myPlugin: RayPlugin = { name: 'my-plugin', version: '1.0.0', install(editor) { // ... }, destroy() { // ... }, }; ``` ``` -------------------------------- ### Basic usage of RayEditor Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-tinymce.html Basic usage of RayEditor: import the library and its CSS, then instantiate with a selector and options. Works offline without an API key. ```javascript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/dist/ray-editor.css'; const editor = new RayEditor('#editor', { placeholder: 'Start typing...', theme: 'light', }); ``` -------------------------------- ### BlogPreview component renders HTML with dangerouslySetInnerHTML Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/react-blog-editor-markdown.html Use this component to display the HTML output from the RayEditor. It takes an `html` prop and renders it inside a div with the `prose` class, enabling rich text styling. This is the live preview panel in the editor layout. ```jsx // components/BlogPreview.jsx export default function BlogPreview({ html }) { return (

Preview

); } ``` -------------------------------- ### Set darkMode on initialization Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-dark-mode.html Initializes RayEditor with the darkMode option set to 'dark' or 'auto'. The 'auto' value follows the OS preference using prefers-color-scheme. Requires importing the RayEditor package and its CSS. ```javascript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/dist/ray-editor.css'; // Always dark const editor = new RayEditor(document.getElementById('editor'), { darkMode: 'dark' }); // Follow OS preference const editor2 = new RayEditor(document.getElementById('editor2'), { darkMode: 'auto' }); ``` -------------------------------- ### RayEditor in Headless WordPress React Frontend Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/wysiwyg-editor-wordpress.html Demonstrates fetching post content from the WordPress REST API and binding it to the RayEditor React component. ```javascript // Fetch content from WP REST API and edit with RayEditor import RayEditor from '@rohanyeole/ray-editor-react'; function PostEditor({ postId }) { const [content, setContent] = React.useState(''); React.useEffect(() => { fetch(`/wp-json/wp/v2/posts/${postId}`) .then(r => r.json()) .then(p => setContent(p.content.rendered)); }, [postId]); return ; } ``` -------------------------------- ### Enable Markdown mode with toolbar items Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/implement-markdown-mode.html Adds markdownToggle, importMarkdown, and exportMarkdown to the toolbar array. Requires importing the RayEditor class and its CSS. ```javascript import { RayEditor } from '@rohanyeole/ray-editor'; import '@rohanyeole/ray-editor/dist/ray-editor.css'; const editor = new RayEditor(document.getElementById('editor'), { toolbar: [ 'bold', 'italic', 'heading', 'orderedList', 'unorderedList', 'codeBlock', 'link', 'table', '|', 'markdownToggle', // click to toggle raw Markdown view 'importMarkdown', // opens file picker for .md files 'exportMarkdown' // downloads content as .md file ] }); ``` -------------------------------- ### editor.use(plugin) Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Registers a plugin with the editor. ```APIDOC ## editor.use(plugin) ### Description Registers a plugin with the editor. ### Method POST ### Endpoint editor.use(plugin) ### Parameters #### Request Body - **plugin** (object) - Required - The plugin object with a `name` string and an `install(ed)` function. ### Example ```js editor.use({ name: 'my-plugin', install(ed) { /* ... */ } }); ``` ``` -------------------------------- ### Method: editor.on(eventName, callback) Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Documentation for the editor.on method used to subscribe to editor events. ```APIDOC ## [METHOD] editor.on(eventName, callback) ### Description Registers a listener for a specific editor event. The callback receives the event payload (if any). ### Method `on` ### Parameters - **eventName** (string) - Required - The name of the event to listen for (e.g., `content:change`, `selection:change`, `focus`, `blur`). - **callback** (function) - Required - The function to call when the event fires. The callback receives the event payload (e.g., `html` for `content:change`). ### Example ```typescript editor.on('content:change', (html) => { console.log('changed:', html.length, 'chars'); }); ``` ``` -------------------------------- ### Basic usage of TinyMCE with React Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/rayeditor-vs-tinymce.html Basic usage of TinyMCE with React. Requires an API key even in development. ```jsx import { Editor } from '@tinymce/tinymce-react'; ``` -------------------------------- ### NewPostPage assembles editor and preview with save handler Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/react-blog-editor-markdown.html This page component combines the BlogEditor and BlogPreview in a two-column grid. It lazy-loads the editor to avoid SSR issues and handles saving by posting the HTML to `/api/posts`. The `handleSave` function updates the content state and sends a POST request. ```jsx // pages/new-post.jsx (Next.js) or App.jsx import dynamic from 'next/dynamic'; import BlogPreview from '../components/BlogPreview'; import { useState } from 'react'; // Lazy-load to avoid SSR issues const BlogEditor = dynamic(() => import('../components/BlogEditor'), { ssr: false }); export default function NewPostPage() { const [content, setContent] = useState({ html: '' }); const handleSave = async ({ html }) => { setContent({ html }); // POST to your CMS or API await fetch('/api/posts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ html }) }); }; return (
); } ``` -------------------------------- ### Enable Slash Commands in RayEditor Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/slash-commands-wysiwyg-editor.html Creates a RayEditor instance with a placeholder and toolbar configuration. Slash commands are enabled by default and activate when the user presses '/' on a blank line, so no additional configuration is needed. ```javascript const editor = new RayEditor(document.getElementById('editor'), { placeholder: 'Type / for commands...', toolbar: ['bold','italic','link','table'] // slash commands are on by default }); ``` -------------------------------- ### React integration with RayEditor Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/blog/implement-markdown-mode.html Shows how to use RayEditor in a React component with value and onChange props, and a toolbar that includes the Markdown items. ```jsx ``` -------------------------------- ### editor.setTheme(theme) Source: https://github.com/yeole-rohan/ray-editor/blob/main/examples/docs.html Sets the editor theme to 'light', 'dark', or 'auto'. ```APIDOC ## editor.setTheme(theme) ### Description Sets the editor theme to 'light', 'dark', or 'auto'. ### Method POST ### Endpoint editor.setTheme(theme) ### Parameters #### Request Body - **theme** (string) - Required - The theme name: 'light', 'dark', or 'auto'. ### Example ```js editor.setTheme('dark'); ``` ```