110.0k

Rich Editor

PreviousNext

A powerful, block-based rich text editor built entirely with Tailwind CSS and shadcn/ui. Features Notion-style editing, tables, images, custom classes, and more.

Installation

Install the rich-editor component with all dependencies:

pnpm dlx shadcn@latest add https://ui-v4-livid.vercel.app/r/styles/new-york-v4/rich-editor.json

This automatically installs:

  • All required shadcn components (button, card, dialog, popover, etc.)
  • All npm packages (framer-motion, lucide-react, sonner, next-themes, color, etc.)
  • All editor files including hooks and utilities

Configure the theme provider:

The rich editor includes dark mode toggle functionality. To make it work, you need to wrap your app with the ThemeProvider from next-themes.

See Dark Mode Setup for detailed instructions on configuring the theme provider.

Usage

Basic Editor (Empty State)

Start with an empty editor in Notion mode:

import { EditorProvider } from "@/components/ui/rich-editor"
import { Editor } from "@/components/ui/rich-editor/editor"
 
export default function MyEditor() {
  return (
    <EditorProvider>
      <Editor notionBased />
    </EditorProvider>
  )
}

Editor with Initial Content

Load the editor with pre-existing content:

import { EditorProvider } from "@/components/ui/rich-editor"
import type { ContainerNode } from "@/components/ui/rich-editor"
import { createDemoContent } from "@/components/ui/rich-editor/demo-content"
import { Editor } from "@/components/ui/rich-editor/editor"
 
export default function MyEditor() {
  const initialContainer: ContainerNode = {
    id: "root",
    type: "container",
    children: createDemoContent(),
    attributes: {},
  }
 
  return (
    <EditorProvider initialContainer={initialContainer}>
      <Editor notionBased />
    </EditorProvider>
  )
}

Custom Upload Handler

Integrate with your backend for image and video uploads using a single handler:

import { EditorProvider } from "@/components/ui/rich-editor"
import { Editor } from "@/components/ui/rich-editor/editor"
 
export default function MyEditor() {
  const handleUpload = async (file: File): Promise<string> => {
    // Upload to your backend API (handles both images and videos)
    const formData = new FormData()
    formData.append("file", file)
 
    const response = await fetch("/api/upload", {
      method: "POST",
      body: formData,
    })
 
    const data = await response.json()
    return data.url // Return the permanent URL
  }
 
  return (
    <EditorProvider>
      <Editor notionBased onUploadImage={handleUpload} />
    </EditorProvider>
  )
}

Features

✨ Version 0.2.0 - New Features!

  • 🎨 Notion-Style Mode - Cover images and enhanced first-block styling
  • 🖼️ Free-Floating Images - Drag images anywhere with resize handles and z-index control
  • 📝 Simplified Lists - Easy-to-use bulleted (li) and numbered (ol) lists
  • 🎯 Template Switcher - Blog, Gallery, and Halloween templates with one-click switching
  • 🐛 Mobile Drag & Drop - Full touch support with visual feedback
  • ✨ Bug Fixes - Selection improvements, better image handling, enhanced video blocks

Core Features

  • 📋 Block-Based Architecture - Every element is an independent, draggable block
  • ✨ Rich Text Formatting - Bold, italic, underline, strikethrough, and combinations
  • 🎨 Inline Element Types - Mix H1-H6 styles and inline code within paragraphs
  • 🎨 Color Support - Preset Tailwind colors + custom hex/RGB colors
  • 📏 Font Size Control - Preset sizes + custom pixel values
  • 🎨 Background Colors - Apply backgrounds to any block with presets or custom colors
  • 📊 Advanced Tables - Drag columns/rows, resize, markdown import, and cell formatting
  • 🖼️ Image Management - Multi-select with Ctrl+Click, drag & drop, grid layouts, free positioning
  • 🔗 Smart Links - Modern link popover with URL management
  • ✏️ Custom Tailwind Classes - Apply any Tailwind class with smart class picker
  • ⌨️ Keyboard Shortcuts - Full keyboard navigation and formatting shortcuts
  • 📱 Mobile Optimized - Sheet drawers, touch-friendly controls, automatic keyboard management
  • 🌙 Dark Mode - Full dark mode support out of the box
  • 🔄 Undo/Redo - Complete history management with Ctrl+Z/Ctrl+Y
  • 📤 HTML Export - Export your content to clean, semantic HTML
  • 👁️ Read-Only Mode - Perfect for displaying published content

Examples

Editor with Content

Custom Upload Handler

Read-Only Mode

API Reference

EditorProvider

Wraps your editor and provides the context for all editor operations.

PropTypeDefaultDescription
initialContainerContainerNode-The initial content structure for the editor
debugbooleanfalseShow debug panel with state information
childrenReactNode-Editor components to render

Editor

The main editor component that renders the editing interface.

PropTypeDefaultDescription
readOnlybooleanfalseEnable read-only mode (disables editing)
notionBasedbooleantrueEnable Notion-style mode with cover images and enhanced styling
onUploadImage(file: File) => Promise<string>-Custom upload handler for images and videos. Should return the URL of the upload

ContainerNode

The root node type for editor content.

interface ContainerNode {
  id: string
  type: "container"
  children: EditorNode[]
  attributes: Record<string, any>
}

EditorNode

Editor nodes can be text blocks, images, tables, flex containers, or nested containers.

type EditorNode = TextNode | ContainerNode
 
interface TextNode {
  id: string
  type:
    | "p"
    | "h1"
    | "h2"
    | "h3"
    | "h4"
    | "h5"
    | "h6"
    | "blockquote"
    | "code"
    | "li"
    | "ol"
    | "table"
    | "thead"
    | "tbody"
    | "tr"
    | "th"
    | "td"
    | "img"
    | "video"
  content?: string
  children?: InlineNode[]
  attributes?: Record<string, any>
  styles?: Record<string, string>
}
 
interface InlineNode {
  content: string
  bold?: boolean
  italic?: boolean
  underline?: boolean
  strikethrough?: boolean
  code?: boolean
  elementType?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "code"
  href?: string
  className?: string
  styles?: Record<string, string>
}

Keyboard Shortcuts

ShortcutAction
Ctrl/Cmd + BToggle bold
Ctrl/Cmd + IToggle italic
Ctrl/Cmd + UToggle underline
Ctrl/Cmd + ZUndo
Ctrl/Cmd + Shift + ZRedo
EnterCreate new block after
Shift + EnterCreate nested block
Ctrl/Cmd + KInsert link
Ctrl + ClickMulti-select images
Delete/BackspaceDelete block (when empty)
- (dash space)Convert to bulleted list
1. (number period)Convert to numbered list
/Open command menu (planned)

Block Types

The editor supports the following block types:

  • Paragraph (p) - Standard text content with inline formatting
  • Headings (h1-h6) - Six levels of headings for document structure
  • Blockquote - Styled quotes and callouts with custom backgrounds
  • Code Block - Syntax-friendly code display
  • Lists (li/ol) - Bulleted and numbered lists with auto-conversion
  • Table - Full-featured tables with drag, resize, and formatting
  • Image - Single images, grid layouts, and free-positioned images
  • Video - Embedded video with playback controls
  • Container - Nested blocks for hierarchical content organization

Customization

Accessing Editor State

Access the editor state and actions through the context:

import {
  useEditorState,
  useEditorDispatch,
  useContainer,
} from "@/components/ui/rich-editor/store/editor-store"
 
function MyComponent() {
  const state = useEditorState()
  const dispatch = useEditorDispatch()
  const container = useContainer()
 
  // Access current content
  console.log(container)
 
  // Access selection
  console.log(state.currentSelection)
 
  // Dispatch actions
  dispatch({ type: "ADD_BLOCK", payload: { ... } })
}

Export to HTML

Export your content to HTML for storage or display:

import { serializeToHTML } from "@/components/ui/rich-editor/utils/serialize-to-html"
 
const html = serializeToHTML(container)

Custom Classes

Apply any Tailwind CSS class to text or blocks using the Custom Class Popover:

  1. Select text
  2. Click the pencil icon (✏️) in the selection toolbar
  3. Search for classes or type custom ones
  4. Apply gradients, shadows, borders, backgrounds, and more!

Example classes you can apply:

  • Gradients: bg-gradient-to-r from-purple-600 to-pink-600 bg-clip-text text-transparent
  • Shadows: drop-shadow-lg text-blue-600
  • Borders: border-2 border-green-600 px-2 rounded
  • Backgrounds: bg-yellow-200 dark:bg-yellow-800 px-2 py-1 rounded

Notion-Style Mode

Enable Notion-style features with the notionBased prop:

<Editor notionBased />

Features in Notion mode:

  • Cover Images - Beautiful header images with drag-to-reposition
  • First Block Styling - Automatic large heading for document titles
  • Enhanced Spacing - Optimized padding and margins
  • Modern Layout - Centered content with proper max-width

Templates

The editor includes pre-designed templates accessible via the Template Switcher button:

Blog Template

Perfect for articles and blog posts with:

  • Professional typography
  • Metadata sections
  • Table of contents structure
  • Code examples

Ideal for photographers and artists:

  • Image-focused layout
  • Multiple grid configurations
  • Caption support
  • Portfolio-ready design

Halloween Template

Festive seasonal design with:

  • Themed colors and styling
  • Special decorative elements
  • Holiday-appropriate content

Mobile Optimization

The editor is fully optimized for mobile devices:

  • Touch-Friendly Controls - Large tap targets for all buttons
  • Sheet Drawers - Mobile-optimized panels for tables, images, and settings
  • Drag & Drop - Full touch support with visual feedback
  • Keyboard Management - Automatic keyboard handling for inputs
  • Responsive Layout - Adapts seamlessly to all screen sizes

Notes

  • The editor uses Framer Motion for animations. Make sure it's installed.
  • Images are stored as base64 by default. Provide a custom upload handler for production use.
  • The editor is mobile-responsive and uses Sheet components on smaller screens.
  • All colors and classes use Tailwind CSS and follow shadcn/ui design patterns.
  • Built with TypeScript for excellent IntelliSense and type safety.
  • State management uses reducers for predictable updates and undo/redo support.

Demo Content

The createDemoContent() function returns a comprehensive example document showcasing:

  • All text formatting options
  • Every block type
  • Color and font size examples
  • Image layouts
  • Tables
  • Nested containers
  • Links and custom classes
  • Keyboard shortcuts reference
  • Feature documentation

Perfect for testing and learning how to structure your own content!

Credits

Created by Mina Massoud