Skip to main content

Overview

The Yoopta Editor is the main component that orchestrates all plugins, tools, and marks. It provides a flexible and powerful API for building rich-text editing experiences.

Creating an Editor Instance

Use createYooptaEditor() to create an editor instance:
import { createYooptaEditor } from '@yoopta/editor';

const editor = useMemo(() => createYooptaEditor(), []);
Always wrap createYooptaEditor() in useMemo to prevent recreating the editor on every render.

Editor Component Props

The YooptaEditor component accepts the following props:

Required Props

editor
YooEditor
required
The editor instance created with createYooptaEditor()
plugins
YooptaPlugin[]
required
Array of plugin instances

Optional Props

value
YooptaContentValue
default:"undefined"
The editor content value
onChange
(value: YooptaContentValue, options: YooptaOnChangeOptions) => void
Callback fired when content changes
onPathChange
(path: YooptaPath) => void
Callback fired when the selection path changes
tools
Partial<Tools>
Object containing tool configurations
marks
YooptaMark[]
Array of mark instances for text formatting
placeholder
string
default:"''"
Placeholder text shown when editor is empty
autoFocus
boolean
default:"true"
Whether to focus the editor on mount
readOnly
boolean
default:"false"
Whether the editor is in read-only mode
className
string
CSS class name for the editor wrapper
style
CSSProperties
Inline styles for the editor wrapper
width
number | string
default:"400px"
Editor width (deprecated, use style object)
selectionBoxRoot
HTMLElement | React.MutableRefObject<HTMLElement | null> | false
default:"document"
Root element for the selection box
id
number | string
Unique identifier for the editor instance

Basic Example

import { useMemo, useState } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import Paragraph from '@yoopta/paragraph';

const plugins = [Paragraph];

export default function MyEditor() {
  const editor = useMemo(() => createYooptaEditor(), []);
  const [value, setValue] = useState();

  const onChange = (newValue, options) => {
    setValue(newValue);
    console.log('Editor changed:', options);
  };

  return (
    <YooptaEditor
      editor={editor}
      plugins={plugins}
      value={value}
      onChange={onChange}
      placeholder="Start typing..."
      autoFocus
    />
  );
}

Content Value Structure

The YooptaContentValue is an object where keys are block IDs and values are block data:
type YooptaContentValue = {
  [blockId: string]: YooptaBlock;
};

type YooptaBlock = {
  id: string;
  type: string;
  meta: {
    order: number;
    depth: number;
  };
  value: any[];
};

Example Content Value

{
  "block-1": {
    "id": "block-1",
    "type": "Paragraph",
    "meta": {
      "order": 0,
      "depth": 0
    },
    "value": [
      {
        "id": "text-1",
        "type": "paragraph",
        "children": [{ "text": "Hello World!" }]
      }
    ]
  }
}

onChange Options

The onChange callback receives options with useful information:
type YooptaOnChangeOptions = {
  // The operation that triggered the change
  operation?: 'insert' | 'update' | 'delete' | 'move';

  // The block that was changed
  blockId?: string;

  // Whether the change was from undo/redo
  historyChange?: boolean;
};

Editor Lifecycle

import { useEffect } from 'react';

export default function MyEditor() {
  const editor = useMemo(() => createYooptaEditor(), []);
  const [value, setValue] = useState();

  useEffect(() => {
    // Editor is mounted and ready
    console.log('Editor ready:', editor);

    return () => {
      // Cleanup when editor unmounts
      console.log('Editor unmounting');
    };
  }, [editor]);

  return <YooptaEditor editor={editor} plugins={plugins} value={value} onChange={setValue} />;
}

Styling the Editor

Using className

<YooptaEditor editor={editor} plugins={plugins} className="my-custom-editor" />
.my-custom-editor {
  max-width: 800px;
  margin: 0 auto;
  padding: 40px 20px;
  min-height: 500px;
}

Using style object

<YooptaEditor
  editor={editor}
  plugins={plugins}
  style={{
    maxWidth: '800px',
    margin: '0 auto',
    padding: '40px 20px',
    minHeight: '500px',
  }}
/>

Multiple Editors

You can have multiple editor instances on the same page:
function MultipleEditors() {
  const editor1 = useMemo(() => createYooptaEditor(), []);
  const editor2 = useMemo(() => createYooptaEditor(), []);

  const [value1, setValue1] = useState();
  const [value2, setValue2] = useState();

  return (
    <>
      <YooptaEditor
        editor={editor1}
        plugins={plugins}
        value={value1}
        onChange={setValue1}
        id="editor-1"
      />

      <YooptaEditor
        editor={editor2}
        plugins={plugins}
        value={value2}
        onChange={setValue2}
        id="editor-2"
      />
    </>
  );
}

Next Steps