yoopta-editor/Yoopta-Editor
 Watch   
 Star   
 Fork   
2026-03-16 20:45:23
Yoopta-Editor

v6.0.2

[6.0.2] - 2026-03-16

Fixed

  • Marks in Table plugin: Fixed bold, italic, underline, and other marks not toggling inside table cells. Removed Range.isExpanded guard from the editor's onKeyDown handler so mark hotkeys work with both collapsed and expanded selections. (#592)
  • Multi-block mark undo: Applying marks (bold, italic, highlight, etc.) across multiple selected blocks now undoes in a single Cmd+Z step instead of block-by-block. Wrapped toggle, addMark, removeMark, and update multi-block loops in editor.batchOperations(). (#592)
  • Video/Embed inline toolbar not showing: Fixed inline toolbar not appearing for video and embed blocks. Replaced Rnd callback ref with a regular div ref (same pattern as image) so the floating toolbar reference is available on mount. (#592)
  • Resize handles visibility on dark content: Changed resize handle styling for image, video, and embed from bg-primary to white handles with border and drop shadow (bg-white border border-border shadow-[0_0_4px_rgba(0,0,0,0.3)]) for consistent visibility on any background. (#592)
  • Placeholder support for nested plugins: Fixed placeholders not showing in nested plugin elements (e.g., Steps). decorate now resolves placeholder from the closest parent element instead of only the root element. (#592)

Changed

  • Media resize defaults: Removed hardcoded 650px/550px default sizes from image, embed, and video render components in shadcn theme. Max sizes now derive from actual editor container width via ResizeObserver, with no artificial limits. (#592)

Added

  • Placeholder documentation: Added comprehensive Placeholders section to docs/core/editor.mdx covering editor-level, element-level, nested plugin, and CSS styling. Updated docs/core/plugins.mdx with extended placeholder field docs and cross-references. (#592)
2026-02-27 19:03:06
Yoopta-Editor

v6.0.1

[6.0.1] - 2026-02-27

Fixed

  • Email serialization: Fixed getEmail to check for valid root elements and handle invalid input gracefully in serializeTextNodes. Refactored callout and list plugins to use centralized theme styles for consistent email output. (#575)
  • Media plugins max size: Removed hardcoded maxWidth/maxHeight from embed, image, and video plugins. Default sizing now uses Infinity for better responsiveness. (#584)

Added

  • Highlight color removal: Added a button to the HighlightColorPicker to remove/reset background or text color. (#582)
  • Element operation tests: Added comprehensive test suites for deleteElement and updateElement functions, covering selection, path, and custom matchers. (#581)
  • Placeholders: Implemented per-element placeholders via .extend() and global editor placeholder. Added placeholder CSS to shadcn theme. (#583)

Changed

  • Theme CSS variables: Removed --yoopta-shadcn-* prefix from CSS variables. Theme now reads standard shadcn variables (--card, --foreground, --border, etc.) directly. Removed @tailwind base to prevent overriding user styles. variables.css is no longer auto-imported — users who don't have their own shadcn variables can import it separately. (#574)
2026-02-24 04:39:41
Yoopta-Editor

v6.0.0

Yoopta Editor v6.0.0

Release Date: February 23, 2026

This is a major release that transforms Yoopta into a fully headless, theme-ready editor with a new plugin architecture, real-time collaboration, and modern tooling.


Highlights

  • Headless architecture — Plugins define structure and behavior only; UI is optional and provided by theme packages
  • New UI layer (@yoopta/ui) — Modular, composable UI components rendered as children of <YooptaEditor>
  • Theme system@yoopta/themes-shadcn (production-ready), @yoopta/themes-material (in progress), @yoopta/themes-base
  • Real-time collaboration — New @yoopta/collaboration package powered by Yjs CRDT
  • Namespace APIsBlocks.*, Elements.*, Marks.*, Selection.* for structured editor operations
  • Element buildereditor.y() API for programmatic content creation
  • New plugins — Steps, Tabs, Carousel, Emoji, Mention
  • Email serializereditor.getEmail() for email-compatible HTML output
  • Turborepo + Yarn Berry — Modern monorepo tooling with build caching and selective dev mode

Breaking Changes

Editor creation

Plugins and marks are now passed to createYooptaEditor() instead of the <YooptaEditor> component:

// Before (v4/v5)
<YooptaEditor plugins={plugins} marks={marks} value={value} onChange={onChange} />

// After (v6)
const editor = useMemo(() => createYooptaEditor({ plugins, marks }), []);

<YooptaEditor editor={editor}>
  <YooptaToolbar />
  <YooptaSlashCommandMenu />
  {/* ... */}
</YooptaEditor>

Content management

The value/onChange controlled pattern on the component is removed:

// Set content
editor.setEditorValue(value);

// Listen to changes
editor.on('change', (value) => { ... });

// Or use onChange prop on <YooptaEditor>
<YooptaEditor editor={editor} onChange={(value, { operations }) => { ... }} />

UI components

@yoopta/tools is deprecated. Migrate to @yoopta/ui:

import {
  YooptaToolbar,
  YooptaActionMenuList,
  YooptaSlashCommandMenu,
  YooptaFloatingBlockActions,
  SelectionBox,
} from '@yoopta/ui';

All UI elements are now children of <YooptaEditor> and use useYooptaEditor() internally.


New Features

Headless plugin architecture

Plugins are now purely structural — they define block types, elements, behavior, and parsers without shipping any visual UI. Theme packages provide optional styled renderers:

// Apply theme to all plugins
import { applyTheme } from '@yoopta/themes-shadcn';
const plugins = applyTheme([Paragraph, Callout, Headings.HeadingOne, ...]);

// Or apply to individual plugins
import { CalloutUI } from '@yoopta/themes-shadcn/callout';
const CalloutWithUI = Callout.extend({ elements: CalloutUI });

Namespace APIs

Structured APIs for all editor operations:

import { Blocks, Elements, Marks, Selection } from '@yoopta/editor';

Blocks.insertBlock(editor, { ... });
Blocks.deleteBlock(editor, { ... });
Blocks.toggleBlock(editor, { ... });
Blocks.moveBlock(editor, { ... });
Blocks.duplicateBlock(editor, { ... });
Blocks.splitBlock(editor, { ... });
Blocks.mergeBlock(editor, { ... });
Blocks.increaseBlockDepth(editor, { ... });
Blocks.decreaseBlockDepth(editor, { ... });

Elements.insertElement(editor, { ... });
Elements.updateElement(editor, { ... });
Elements.deleteElement(editor, { ... });
Elements.getElement(editor, { ... });

Marks.update(editor, { type: 'highlight', value: { color: 'red' }, at: [0, 1, 2] });

Element builder (editor.y)

Programmatic content creation:

// Create block element
editor.y('paragraph', { props: {...}, children: [...] });

// Create text node with marks
editor.y.text('Hello', { bold: true, italic: true });

// Create inline element
editor.y.inline('link', { props: { url: '...' }, children: [...] });

Event system

editor.on('change', (value) => { ... });
editor.on('focus', () => { ... });
editor.on('blur', () => { ... });
editor.on('block:copy', (data) => { ... });
editor.on('path-change', (paths) => { ... });
editor.once('change', handler);
editor.off('change', handler);

ElementOptions (@yoopta/ui)

Compound component for inline element configuration popovers, built on Radix UI:

<ElementOptions.Root blockId={blockId} element={element}>
  <ElementOptions.Trigger />
  <ElementOptions.Content>
    <ElementOptions.Group label="Settings">
      <ElementOptions.Select options={options} />
      <ElementOptions.Toggle />
      <ElementOptions.Slider />
      <ElementOptions.ColorPicker />
      <ElementOptions.Input />
    </ElementOptions.Group>
  </ElementOptions.Content>
</ElementOptions.Root>

Hooks: useElementOptions() and useUpdateElementProps<T>().

Real-time collaboration (@yoopta/collaboration)

New core package for collaborative editing:

  • Technology: Yjs CRDT for conflict-free sync with Slate-Yjs binding
  • Features: Awareness, remote cursors, selection tracking
  • Infrastructure: WebSocket provider support
  • Hooks: useCollaboration, useConnectionStatus, useRemoteCursors
import { useCollaboration } from '@yoopta/collaboration';

Email serializer

const emailHTML = editor.getEmail(content, {
  head: { title: 'My Email' },
  body: { attrs: { style: { width: '600px' } } },
  customTemplate: (content) => `<html>...${content}...</html>`,
});

All 23 plugins include email parsers with table-based layouts for email client compatibility.

New plugins

  • Steps — Numbered step-by-step lists with heading and content per step
  • Tabs — Tabbed content containers (renders as sections in email)
  • Carousel — Horizontally scrollable content cards
  • Emoji — Emoji insertion with dropdown picker
  • Mention — @mention with dropdown, avatar support, floating position, extend render

Table plugin enhancements

  • scrollable prop (default: true) — tables respect column widths and scroll horizontally
  • Column resize handles with portal rendering
  • Improved column/row controls positioning in scrollable tables

JSON clipboard support

Copy/paste preserves Yoopta block structure via JSON clipboard data.


Bug Fixes

Editor core

  • Block focus on click — Fixed brief focus jump to the first block when clicking other blocks
  • SelectionBox scroll — Auto-scrolling when dragging selections near viewport edges; selection origin tracks document coordinates
  • SelectionBox — Eliminated native text selection during programmatic block selection

Lists

  • Enter key — Fixed focus loss when pressing Enter in bulleted, numbered, and todo lists (cursor became invisible, especially in Safari)

Image

  • Inline toolbar after upload — Fixed toolbar not appearing after file upload (file picker dialog cleared Slate selection)
  • Left-side resize — Fixed left handle resizing with proper position anchoring
  • Resize handlers — Added white ring styling for visibility on dark images
  • Preview blob leak — Fixed stale closure in useImagePreview where clearPreview() failed to revoke blob URLs
  • Upload validation — Enhanced hooks with validation for upload and delete options

Video

  • Preview blob leak — Fixed same stale closure issue as image plugin in useVideoPreview

FloatingBlockActions

  • Hover detection — Improved reach detection using JavaScript-based extended bounds instead of CSS pseudo-elements
  • Margin offset — Fixed positioning when blocks have margin-top styles

FloatingToolbar

  • Safari — Fixed immediate toolbar closure on button clicks (preventDefault on mouseDown)
  • Safari inline toolbars — Fixed incorrect (0,0) positioning using useLayoutEffect and isReady state

HighlightColorPicker

  • Click-outside handling — Fixed using FloatingOverlay for cross-browser reliability
  • History flooding — Added 300ms debounce to onChange to prevent excessive undo/redo entries

Steps plugin

  • moveUp/moveDown — Fixed buggy methods using proper Transforms.moveNodes

Code/CodeGroup

  • Theme isolation — Shiki theme colors now use scoped CSS variables on elements instead of global document variables

Infrastructure

Turborepo + Yarn Berry migration

  • From: Lerna + Yarn v1
  • To: Turborepo + Yarn Berry (v4)
  • workspace:* protocol resolves local packages correctly
  • Build caching and filtering for selective dev mode
  • Eliminated packages/development/web/next-app-example/ is now the dev workspace

New commands

yarn dev                                    # Start dev server
yarn dev --filter=@yoopta/editor            # Dev + watch one package
yarn dev --filter=@yoopta/editor --filter=@yoopta/paragraph  # Watch multiple
yarn build --filter=@yoopta/editor          # Build single package

Publishing

Versioning uses Changesets with fixed version groups — all @yoopta/* packages share the same version.

React 19

Monorepo upgraded to React 19 while maintaining backward compatibility via peerDependencies: "react": ">=18.2.0".


Migration Guide

1. Update packages

npm install @yoopta/editor@^6.0.0 @yoopta/ui@^6.0.0
# Install theme if desired
npm install @yoopta/themes-shadcn@^6.0.0

2. Update editor creation

// Old
const editor = useMemo(() => createYooptaEditor(), []);
<YooptaEditor editor={editor} plugins={plugins} marks={marks} value={value} onChange={onChange} />

// New
const editor = useMemo(() => createYooptaEditor({ plugins, marks, value: initialValue }), []);
<YooptaEditor editor={editor} onChange={(value, { operations }) => { ... }}>
  {/* UI components as children */}
</YooptaEditor>

3. Replace @yoopta/tools with @yoopta/ui

import {
  YooptaToolbar,
  YooptaActionMenuList,
  YooptaSlashCommandMenu,
  YooptaFloatingBlockActions,
} from '@yoopta/ui';

4. Apply theme (optional)

import { applyTheme } from '@yoopta/themes-shadcn';
const plugins = applyTheme([Paragraph, Callout, ...]);

5. Content handling

// Set value
editor.setEditorValue(savedContent);

// Get value
const content = editor.getEditorValue();

Package Versions

All @yoopta/* packages are published at version 6.0.0:

Package Description
@yoopta/editor Core editor engine
@yoopta/ui UI components (toolbar, menus, block actions, element options, selection box)
@yoopta/collaboration Real-time collaboration (Yjs)
@yoopta/exports HTML/Markdown/PlainText/Email serializers
@yoopta/marks Text formatting (Bold, Italic, Underline, Strike, Code, Highlight)
@yoopta/themes-shadcn Shadcn UI theme
@yoopta/themes-material Material Design theme (in progress)
@yoopta/themes-base Base theme
@yoopta/paragraph Paragraph plugin
@yoopta/headings HeadingOne, HeadingTwo, HeadingThree
@yoopta/lists BulletedList, NumberedList, TodoList
@yoopta/blockquote Blockquote plugin
@yoopta/callout Callout plugin
@yoopta/code Code block plugin
@yoopta/image Image plugin
@yoopta/video Video plugin
@yoopta/embed Embed plugin
@yoopta/file File plugin
@yoopta/link Link plugin
@yoopta/divider Divider plugin
@yoopta/table Table plugin
@yoopta/accordion Accordion plugin
@yoopta/mention Mention plugin
@yoopta/emoji Emoji plugin
@yoopta/steps Steps plugin
@yoopta/tabs Tabs plugin
@yoopta/carousel Carousel plugin
@yoopta/table-of-contents Table of Contents plugin
2026-02-19 20:55:16
Yoopta-Editor

v6.0.0-beta.22

[6.0.0-beta.22] - 2026-02-19

Changed

  • Monorepo: Lerna → Turborepo + Yarn Berry: Migrated from Lerna + Yarn v1 to Turborepo + Yarn Berry (v4). workspace:* protocol now resolves local packages correctly (fixes broken symlinks with prerelease versions). Turborepo provides build caching and --filter for selective dev mode.
  • Dev workflow: yarn dev starts the dev server. Use yarn dev --filter=@yoopta/editor to watch specific packages — replaces the old PACKAGES="..." yarn dev workaround.
  • Dev playground: Removed packages/development/. The web/next-app-example/ app is now the development workspace.
  • Publishing: Lerna → Changesets: Versioning and publishing now uses Changesets with fixed version groups — all @yoopta/* packages share the same version.
  • React 19: Upgraded monorepo to React 19. Packages keep peerDependencies: "react": ">=18.2.0" for backwards compatibility.

Added

  • @yoopta/emoji: New plugin for emoji insertion (added in beta.21, first included in workspace build).
2026-02-17 20:42:18
Yoopta-Editor

v6.0.0-beta.21

[6.0.0-beta.21] - 2026-02-17

Fixed

  • List plugins (Enter key): Fixed focus loss when pressing Enter in bulleted, numbered, and todo lists — cursor would become invisible and typing stopped working (especially in Safari). Removed unnecessary Editor.withoutNormalizing wrapper and added requestAnimationFrame DOM selection re-sync in focusBlock to recover from slate-react's layout effect clearing the selection.
  • Block focus on click: Fixed clicking on a block (e.g., third block) causing a brief focus jump to the first block. Moved editor.focus() call so it only fires when clicking outside any block, not when clicking on a specific block where the browser handles focus natively.
  • SelectionBox scroll: Added auto-scrolling when dragging selection near viewport edges. Selection origin is now tracked in document coordinates so the selection grows correctly as the page scrolls, selecting all blocks between the start position and the current mouse position.
  • Image inline toolbar after upload: Fixed image inline toolbar not appearing immediately after file upload. The file picker dialog steals browser focus and clears the Slate selection; now focusBlock is called after upload to restore selection so the toolbar renders instantly.
  • Image/Video preview blob leak: Fixed stale closure bug in useImagePreview and useVideoPreview where clearPreview() would fail to revoke the blob URL when called from async upload callbacks. Preview URL is now tracked via a ref to avoid stale state in closures.
2026-02-12 19:50:51
Yoopta-Editor

v6.0.0-beta.20

Added

  • @yoopta/collaboration: New core package for real-time collaborative editing. Uses Yjs CRDT for conflict-free sync, with Slate ↔ Yjs binding, awareness (presence), remote cursors and selection, and WebSocket provider support. Hooks: useCollaboration, useConnectionStatus, useRemoteCursors. See docs/core/collaboration and the Collaboration example.

Full Changelog: https://github.com/yoopta-editor/Yoopta-Editor/compare/v6.0.0-beta.19...v6.0.0-beta.20

2026-02-07 05:41:35
Yoopta-Editor

v6.0.0-beta.19

[6.0.0-beta.19] - 2026-02-07

Added

  • ElementOptions (@yoopta/ui): New compound component for inline element configuration popovers. Includes Root, Trigger, Content, Group, Label, Separator, Select, Toggle, Slider, ColorPicker, and Input components. Built on Radix UI primitives.
  • ElementOptions hooks: Added useElementOptions() and useUpdateElementProps<T>() helper hooks for accessing element context and updating properties.
  • Table plugin: Added scrollable prop (default: true) - tables now respect column widths and scroll horizontally when wider than container.
  • Documentation: Added comprehensive ElementOptions documentation with API reference and examples.

Fixed

  • FloatingBlockActions: Fixed positioning when blocks have margin-top styles. Now finds [data-element-type] element and accounts for its margin offset.
  • Table controls: Fixed column controls, add row/column buttons appearing outside visible bounds when table is scrollable. Controls now stay within the visible scroll container area.
  • ElementOptions ColorPicker: Added debounced onChange (300ms) to prevent flooding undo/redo history, plus HexColorInput field and swatch preview.

Changed

  • ElementOptions: Migrated from floating-ui to Radix UI Popover for better accessibility and positioning.

Full Changelog: https://github.com/yoopta-editor/Yoopta-Editor/compare/v6.0.0-beta.18...v6.0.0-beta.19

2026-02-05 02:57:55
Yoopta-Editor

v6.0.0-beta.18

What's Changed

Fixed

  • FloatingBlockActions: Fixed hover detection - users can now reliably reach floating actions when moving cursor from block to actions. Uses JavaScript-based extended bounds checking instead of CSS pseudo-elements.
  • FloatingToolbar (Safari): Fixed button clicks immediately closing the toolbar in Safari by adding preventDefault() on mouseDown.
  • HighlightColorPicker: Fixed click-outside handling using FloatingOverlay approach for reliable behavior across browsers including Safari.
  • HighlightColorPicker: Added debounce (300ms) to color picker onChange to prevent flooding undo/redo history with every color change.
  • SelectionBox: Fixed native text selection appearing during programmatic block selection by preventing default and setting user-select: none.
  • Steps plugin: Fixed buggy moveUp and moveDown methods - now properly uses Transforms.moveNodes and recalculates order values.
  • Inline toolbars positioning (Safari): Fixed image, file, embed, and video inline toolbars appearing at top-left corner (0,0) in Safari. Now uses useLayoutEffect, isReady state guard, and FloatingPortal for proper positioning.
  • Image resize handlers: Added contrasting white ring (ring-2 ring-white/80) for visibility on dark images.
  • Image resize (left handle): Fixed buggy left-side resizing by anchoring position with position={{ x: 0, y: 0 }}.

Changed

  • Code/CodeGroup themes: Shiki theme colors now use scoped CSS variables on elements instead of global document variables for better isolation.
2026-01-19 22:24:44
Yoopta-Editor

v6.0.0-beta.0

What's Changed

V6 Changes

Major version with significant API and architectural changes


Summary

  • Editor creation: Plugins, value and marks are passed to createYooptaEditor(), not to <YooptaEditor>.
  • Content: No value / onChange controlled pattern on the component;
  • UI: All UI (toolbar, slash menu, block actions, etc.) are children of <YooptaEditor> and use useYooptaEditor() from context.
  • Packages: Headless core, separate @yoopta/ui, themes (@yoopta/themes-shadcn), namespace APIs (Blocks, Elements, Marks, Selection).
  • Docs & examples: Documentation and examples updated for the new API.

Breaking changes

1. Editor creation and YooptaEditor props

Before (master / 4.9.x):

const editor = useMemo(() => createYooptaEditor(), []);

<YooptaEditor
  editor={editor}
  plugins={plugins}
  marks={marks}
  value={value}
  onChange={setValue}
  placeholder="..."
/>;

After (v6):

const editor = useMemo(() => createYooptaEditor({ plugins, marks, value: initialValue}), []);

<YooptaEditor
  editor={editor}
  onChange={(value) => {
    /* persist or setState */
  }}
  placeholder="Type / to open menu...">
  {/* UI components as children */}
</YooptaEditor>;
  • plugins and marks are required in createYooptaEditor({ plugins, marks }) and must not be passed to <YooptaEditor>.
  • value is not a prop of <YooptaEditor>. Use editor.setEditorValue(data) for initial/loaded content and onChange to react to changes.
  • To read content: editor.getEditorValue() (or use the value passed to onChange).

2. Optional initial value at creation

You can still pass initial content when creating the editor:

createYooptaEditor({ plugins, marks, value: initialContent, readOnly: false });

Or set it later in useEffect with editor.setEditorValue(initialContent).

3. UI components as children

Before (master): Tools or toolbar could be passed as props or a separate layer.

After (v6): All UI that needs the editor must be children of <YooptaEditor> so they can use useYooptaEditor():

<YooptaEditor editor={editor} onChange={onChange} placeholder="...">
  <FloatingToolbar />
  <FloatingBlockActions />
  <SlashCommandMenu />
  <SelectionBox selectionBoxElement={containerRef} />
</YooptaEditor>
  • FloatingToolbar, ActionMenuList, SlashCommandMenu, FloatingBlockActions, BlockOptions, SelectionBox come from @yoopta/ui.
  • For drag-and-drop: wrap with BlockDndContext and use renderBlock with SortableBlock (and optional DragHandle).

4. Deprecated / removed patterns

  • @yoopta/tools (e.g. ActionMenuTool, Toolbar, LinkTool): deprecated; use components from @yoopta/ui instead.
  • <YooptaEditor tools={[...]} />: no longer supported; use children as above.
  • value / controlled value on <YooptaEditor>: removed; use setEditorValue + onChange.

New or changed API

createYooptaEditor(options)

  • plugins (required): array of plugin instances.
  • marks (optional): array of mark types (e.g. Bold, Italic).
  • value (optional): initial YooptaContentValue.
  • readOnly (optional): boolean.
  • id (optional): custom editor id.

YooptaEditor props

  • editor (required): instance from createYooptaEditor.
  • onChange (optional): (value: YooptaContentValue, options: { operations }) => void.
  • onPathChange (optional): (path: YooptaPath) => void.
  • placeholder, autoFocus, className, style, renderBlock, children.

No plugins, marks, or value.

Editor instance

  • editor.getEditorValue(): returns current YooptaContentValue.
  • editor.setEditorValue(value): sets content (e.g. after load).
  • editor.applyTransforms([{ type: 'validate_block_paths' }]): optional after setEditorValue to normalize paths.
  • Events: editor.on('change', fn), editor.off('change', fn), same for path-change, etc.
  • Block operations: insertBlock, deleteBlock, updateBlock, toggleBlock, moveBlock, focusBlock, etc.
  • Elements: insertElement, updateElement, deleteElement, getElement, getElements, etc.
  • Parsers: getHTML, getMarkdown, getPlainText, getEmail (each can take value or use current).
  • History: undo, redo, batchOperations.

Namespace APIs (optional usage)

From @yoopta/editor you can use:

  • Blocks.*: Blocks.insertBlock(editor, ...), Blocks.deleteBlock(editor, ...), etc.
  • Elements.*: Elements.insertElement(editor, ...), etc.
  • Marks.*: Marks.toggle(editor, { type: 'bold' }), etc.
  • Selection.*: selection helpers.

These mirror methods on the editor instance.


UI package (@yoopta/ui)

  • FloatingToolbar — formatting toolbar (compound: Content, Group, Button, Separator).
  • ActionMenuList — “Turn into” / block type menu (controlled: open, onOpenChange, anchor).
  • SlashCommandMenu — slash “/” command menu (compound: Content, List, Item, Empty, Footer).
  • FloatingBlockActions — hover actions per block (render props with blockId).
  • BlockOptions — block context menu (Duplicate, Delete, Turn into, etc.).
  • SelectionBox — rectangle selection for multiple blocks (selectionBoxElement = container ref).
  • BlockDndContext, SortableBlock, DragHandle — drag-and-drop reorder.

All of these are used as children of <YooptaEditor> and rely on useYooptaEditor().


Themes

The editor and plugins are headless by default. Theme packages provide optional UI for plugin elements. Available: @yoopta/themes-shadcn (production), @yoopta/themes-material (in progress).

Two ways to use theme UI:

  1. Apply to all pluginsapplyTheme(plugins) returns plugins with theme-styled elements. Use: createYooptaEditor({ plugins: applyTheme(plugins), marks }).
  2. Apply to a single plugin — import the theme UI for that plugin and extend: e.g. import { CalloutUI } from '@yoopta/themes-shadcn/callout'; Callout.extend({ elements: CalloutUI }).

CSS is applied by the theme package; no need to pass plugins/marks to <YooptaEditor>.


Package and repo structure

  • Core: @yoopta/editor (headless), @yoopta/ui (UI components), @yoopta/exports (serializers).
  • Plugins: e.g. @yoopta/paragraph, @yoopta/headings, @yoopta/code, @yoopta/table, etc.
  • Marks: @yoopta/marks (Bold, Italic, Underline, etc.).
  • Themes: @yoopta/themes-shadcn, @yoopta/themes-material (in development).
  • Examples: web/next-app-example, web/vite-example, packages/development (playground). Old web/next-example removed or replaced.

  • Getting started, quickstart, installation, introduction: Updated to v6 API (createYooptaEditor({ plugins, marks }), setEditorValue, onChange, UI as children).
  • UI overview and per-component docs (docs/ui/*.mdx): Updated to SlashCommandMenu, compound components, and correct usage (children, no plugins/value on YooptaEditor).
  • Mintlify docs: Plugin previews and plugin playground (iframe) snippets; accordion and other plugin docs aligned with v6.

Migration checklist (from 4.9.x to v6)

  1. Create editor with createYooptaEditor({ plugins, marks }) (and optional value, readOnly).
  2. Remove plugins, marks, and value from <YooptaEditor>.
  3. Set initial content with editor.setEditorValue(data) in useEffect (or pass value into createYooptaEditor).
  4. Keep onChange on <YooptaEditor> and use it (and/or editor.getEditorValue()) for persistence.
  5. Move toolbar, block menu, slash menu, block actions, etc. inside <YooptaEditor> as children.
  6. Replace any @yoopta/tools usage with @yoopta/ui components (FloatingToolbar, ActionMenuList, SlashCommandMenu, etc.).
  7. Optional: Use applyTheme(plugins) when using @yoopta/themes-shadcn.
  8. Optional: Add BlockDndContext, renderBlock with SortableBlock, and SelectionBox as needed.

Version

  • Package versions: e.g. 6.0.0-beta.x for core and related packages.

Full Changelog: https://github.com/yoopta-editor/Yoopta-Editor/compare/v4.9.9...v6.0.0-beta.17

2025-06-12 01:53:25
Yoopta-Editor

v4.9.9

What's Changed

Full Changelog: https://github.com/yoopta-editor/Yoopta-Editor/compare/v4.9.8...v4.9.9