tentap-editor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TenTap Editor

TenTap 编辑器

A typed, customizable, and extendable rich text editor for React Native built on Tiptap and Prosemirror. TenTap provides a bridge architecture that enables seamless communication between React Native and a web-based editor, offering powerful editing capabilities with native mobile performance.
这是一款基于Tiptap和Prosemirror构建的、类型安全的、可定制且可扩展的React Native富文本编辑器。TenTap采用桥接架构,实现了React Native与基于Web的编辑器之间的无缝通信,在提供强大编辑功能的同时保证了原生移动应用的性能。

Core Functionality

核心功能

TenTap Editor delivers comprehensive rich text editing capabilities through a WebView-based architecture that bridges React Native and Tiptap. It provides essential features including text formatting (bold, italic, underline, strikethrough), lists (bullet, ordered, task), headings, blockquotes, code blocks, images, links, colors, and highlights. The editor supports custom themes, dark mode, dynamic CSS injection, custom fonts, and full extensibility through custom bridge extensions.
TenTap编辑器通过基于WebView的桥接架构连接React Native与Tiptap,提供全面的富文本编辑功能。它包含文本格式化(粗体、斜体、下划线、删除线)、列表(项目符号、有序、任务)、标题、块引用、代码块、图片、链接、颜色和高亮等基础功能。编辑器支持自定义主题、深色模式、动态CSS注入、自定义字体,还可通过自定义桥接扩展实现全功能扩展。

When to Use

适用场景

Use TenTap when building mobile applications requiring rich text editing, including chat interfaces, email composers, content management systems, note-taking apps, social media platforms, document editors, or any application where users need to format text beyond plain input. It offers both simple plug-and-play usage for standard features and advanced customization for specialized requirements.
当你构建需要富文本编辑功能的移动应用时,可使用TenTap,包括聊天界面、邮件撰写器、内容管理系统、笔记应用、社交媒体平台、文档编辑器,或任何需要超出纯文本输入格式的应用。它既提供了开箱即用的标准功能,也支持针对特殊需求的高级定制。

Quick Start

快速开始

Installation

安装

React Native:
bash
yarn add @10play/tentap-editor react-native-webview
cd ios && pod install
Expo:
bash
npx expo install @10play/tentap-editor react-native-webview
Note: Expo Go supports only basic usage. For advanced features, use Expo Dev Client.
React Native:
bash
yarn add @10play/tentap-editor react-native-webview
cd ios && pod install
Expo:
bash
npx expo install @10play/tentap-editor react-native-webview
注意:Expo Go仅支持基础用法。如需高级功能,请使用Expo Dev Client。

Basic Setup

基础配置

The simplest implementation requires three components:
useEditorBridge
hook,
RichText
component, and
Toolbar
component.
tsx
import { KeyboardAvoidingView, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { RichText, Toolbar, useEditorBridge } from '@10play/tentap-editor';

export const BasicEditor = () => {
  const editor = useEditorBridge({
    autofocus: true,
    avoidIosKeyboard: true,
    initialContent: '<p>Start editing!</p>',
  });

  return (
    <SafeAreaView style={styles.fullScreen}>
      <RichText editor={editor} />
      <KeyboardAvoidingView
        behavior="padding"
        style={styles.keyboardAvoidingView}
      >
        <Toolbar editor={editor} />
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  fullScreen: { flex: 1 },
  keyboardAvoidingView: {
    position: 'absolute',
    width: '100%',
    bottom: 0,
  },
});
This creates a fully functional rich text editor with standard formatting capabilities. See
references/Basic.tsx
for the complete working example.
最简单的实现需要三个组件:
useEditorBridge
钩子、
RichText
组件和
Toolbar
组件。
tsx
import { KeyboardAvoidingView, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { RichText, Toolbar, useEditorBridge } from '@10play/tentap-editor';

export const BasicEditor = () => {
  const editor = useEditorBridge({
    autofocus: true,
    avoidIosKeyboard: true,
    initialContent: '<p>Start editing!</p>',
  });

  return (
    <SafeAreaView style={styles.fullScreen}>
      <RichText editor={editor} />
      <KeyboardAvoidingView
        behavior="padding"
        style={styles.keyboardAvoidingView}
      >
        <Toolbar editor={editor} />
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  fullScreen: { flex: 1 },
  keyboardAvoidingView: {
    position: 'absolute',
    width: '100%',
    bottom: 0,
  },
});
这将创建一个具备标准格式化功能的完整富文本编辑器。完整的运行示例请查看
references/Basic.tsx

Core Concepts

核心概念

Bridge Architecture

桥接架构

TenTap uses a bridge pattern to communicate between React Native and the Tiptap editor running in a WebView:
  • EditorBridge: Main interface providing all editor commands accessible from React Native
  • BridgeExtension: Typed classes that extend editor functionality by wrapping Tiptap extensions
  • BridgeState: Real-time state object reflecting the editor's current status
This architecture enables powerful features while maintaining type safety and minimizing WebView-Native communication overhead.
TenTap使用桥接模式实现React Native与运行在WebView中的Tiptap编辑器之间的通信:
  • EditorBridge:提供所有可从React Native调用的编辑器命令的主接口
  • BridgeExtension:类型安全的类,通过封装Tiptap扩展来扩展编辑器功能
  • BridgeState:实时反映编辑器当前状态的对象
该架构在保证类型安全的同时,最大限度减少了WebView与原生端的通信开销,从而实现强大的功能。

Usage Patterns

使用模式

Simple Usage: Pre-configured with
TenTapStarterKit
including all standard rich text features. Ideal for most use cases requiring standard formatting capabilities.
Advanced Usage: Custom bundling with Vite for full control over the web editor, custom Tiptap extensions, and specialized bridge implementations. Required when adding custom extensions beyond the pre-built bridges.
简单用法:预配置了
TenTapStarterKit
,包含所有标准富文本功能。适用于大多数需要标准格式化功能的场景。
高级用法:使用Vite进行自定义打包,完全控制Web编辑器、自定义Tiptap扩展和专用桥接实现。当需要添加预构建桥接之外的自定义扩展时,必须使用此模式。

Essential APIs

核心API

useEditorBridge Hook

useEditorBridge钩子

The primary hook for creating and configuring an EditorBridge instance.
Key Configuration Options:
  • bridgeExtensions
    : Array of BridgeExtensions (default:
    TenTapStarterKit
    )
  • initialContent
    : HTML string or JSON object for initial editor content
  • autofocus
    : Auto-focus editor on mount (default: false)
  • avoidIosKeyboard
    : Keep cursor visible above keyboard (default: false, works on both iOS and Android)
  • dynamicHeight
    : WebView height matches content height (default: false)
  • theme
    : Custom theme configuration for native components
  • editable
    : Enable/disable editing (default: true)
  • customSource
    : Custom HTML string for advanced setups
  • onChange
    : Callback fired on content changes
  • DEV
    /
    DEV_SERVER_URL
    : Development mode configuration for advanced setups
tsx
const editor = useEditorBridge({
  autofocus: true,
  avoidIosKeyboard: true,
  initialContent: '<p>Hello, world!</p>',
  bridgeExtensions: [...TenTapStartKit, CustomBridge],
  onChange: () => {
    // Handle content changes (debounce recommended)
  },
});
See
references/useEditorBridge.md
for complete API documentation.
用于创建和配置EditorBridge实例的主要钩子。
关键配置选项
  • bridgeExtensions
    :BridgeExtension数组(默认值:
    TenTapStarterKit
  • initialContent
    :用于编辑器初始内容的HTML字符串或JSON对象
  • autofocus
    :挂载时自动聚焦编辑器(默认值:false)
  • avoidIosKeyboard
    :保持光标在键盘上方可见(默认值:false,支持iOS和Android)
  • dynamicHeight
    :WebView高度匹配内容高度(默认值:false)
  • theme
    :原生组件的自定义主题配置
  • editable
    :启用/禁用编辑功能(默认值:true)
  • customSource
    :用于高级设置的自定义HTML字符串
  • onChange
    :内容变化时触发的回调函数
  • DEV
    /
    DEV_SERVER_URL
    :高级设置的开发模式配置
tsx
const editor = useEditorBridge({
  autofocus: true,
  avoidIosKeyboard: true,
  initialContent: '<p>Hello, world!</p>',
  bridgeExtensions: [...TenTapStartKit, CustomBridge],
  onChange: () => {
    // 处理内容变化(建议使用防抖)
  },
});
完整API文档请查看
references/useEditorBridge.md

EditorBridge API

EditorBridge API

The EditorBridge interface provides comprehensive editor control through the following methods:
Content Management:
  • getHTML()
    : Promise returning HTML content
  • getText()
    : Promise returning plain text content
  • getJSON()
    : Promise returning JSON document structure
  • setContent(content)
    : Set editor content from HTML or JSON
Focus & Selection:
  • focus(pos?)
    : Focus editor at optional position
  • blur()
    : Remove focus and close keyboard
  • setSelection(from, to)
    : Set text selection range
State Retrieval:
  • getEditorState()
    : Get current BridgeState snapshot
  • webviewRef
    : Reference to underlying WebView
Dynamic Styling:
  • injectCSS(css, tag?)
    : Inject or update CSS stylesheets
  • injectJS(js)
    : Execute JavaScript in WebView
Formatting Commands:
  • toggleBold()
    ,
    toggleItalic()
    ,
    toggleUnderline()
    ,
    toggleStrikethrough()
  • toggleHeading(level)
    : Set heading level (1-6)
  • toggleCode()
    : Toggle inline code
  • toggleBlockquote()
    : Toggle blockquote
  • toggleBulletList()
    ,
    toggleOrderedList()
    ,
    toggleTaskList()
  • setColor(color)
    ,
    unsetColor()
    : Set/unset text color
  • setHighlight(color)
    ,
    toggleHighlight(color)
    ,
    unsetHighlight()
    : Text highlighting
  • setLink(url)
    : Insert/update link
  • setImage(src)
    : Insert image
List Management:
  • lift()
    : Outdent list item
  • sink()
    : Indent list item
History:
  • undo()
    ,
    redo()
    : Navigate history
Placeholder:
  • setPlaceholder(text)
    : Update placeholder text dynamically
See
references/EditorBridge.md
for complete API reference with all 30+ methods.
EditorBridge接口通过以下方法提供全面的编辑器控制:
内容管理
  • getHTML()
    :返回HTML内容的Promise
  • getText()
    :返回纯文本内容的Promise
  • getJSON()
    :返回JSON文档结构的Promise
  • setContent(content)
    :通过HTML或JSON设置编辑器内容
聚焦与选区
  • focus(pos?)
    :聚焦编辑器,可指定位置
  • blur()
    :移除焦点并关闭键盘
  • setSelection(from, to)
    :设置文本选区内的范围
状态获取
  • getEditorState()
    :获取当前BridgeState的快照
  • webviewRef
    :底层WebView的引用
动态样式
  • injectCSS(css, tag?)
    :注入或更新CSS样式表
  • injectJS(js)
    :在WebView中执行JavaScript
格式化命令
  • toggleBold()
    toggleItalic()
    toggleUnderline()
    toggleStrikethrough()
  • toggleHeading(level)
    :设置标题级别(1-6)
  • toggleCode()
    :切换行内代码
  • toggleBlockquote()
    :切换块引用
  • toggleBulletList()
    toggleOrderedList()
    toggleTaskList()
  • setColor(color)
    unsetColor()
    :设置/取消文本颜色
  • setHighlight(color)
    toggleHighlight(color)
    unsetHighlight()
    :文本高亮
  • setLink(url)
    :插入/更新链接
  • setImage(src)
    :插入图片
列表管理
  • lift()
    :减少列表项缩进
  • sink()
    :增加列表项缩进
历史记录
  • undo()
    redo()
    :导航历史记录
占位符
  • setPlaceholder(text)
    :动态更新占位符文本
完整的API参考(包含30+方法)请查看
references/EditorBridge.md

State Management Hooks

状态管理钩子

useBridgeState: Subscribe to real-time editor state changes.
tsx
const editorState = useBridgeState(editor);

// Access state properties
editorState.isFocused;      // Editor focus state
editorState.isEmpty;        // Whether editor is empty
editorState.isBoldActive;   // Bold formatting state
editorState.canToggleBold;  // Whether bold can be toggled
editorState.headingLevel;   // Current heading level
BridgeState includes 30+ properties tracking formatting states, capabilities, and editor status. See
references/BridgeState.md
for complete property listing.
useEditorContent: Efficiently retrieve editor content with built-in debouncing.
tsx
const htmlContent = useEditorContent(editor, { type: 'html' });

// Alternative content types
const textContent = useEditorContent(editor, { type: 'text' });
const jsonContent = useEditorContent(editor, { type: 'json' });

// Custom debounce interval (default: 10ms)
const content = useEditorContent(editor, {
  type: 'html',
  debounceInterval: 100,
});
See
references/useEditorContent.md
for complete documentation.
useBridgeState:订阅编辑器状态的实时变化。
tsx
const editorState = useBridgeState(editor);

// 访问状态属性
editorState.isFocused;      // 编辑器聚焦状态
editorState.isEmpty;        // 编辑器是否为空
editorState.isBoldActive;   // 粗体格式化状态
editorState.canToggleBold;  // 是否可以切换粗体
editorState.headingLevel;   // 当前标题级别
BridgeState包含30+属性,用于跟踪格式化状态、功能和编辑器状态。完整属性列表请查看
references/BridgeState.md
useEditorContent:通过内置防抖功能高效获取编辑器内容。
tsx
const htmlContent = useEditorContent(editor, { type: 'html' });

// 其他内容类型
const textContent = useEditorContent(editor, { type: 'text' });
const jsonContent = useEditorContent(editor, { type: 'json' });

// 自定义防抖间隔(默认值:10ms)
const content = useEditorContent(editor, {
  type: 'html',
  debounceInterval: 100,
});
完整文档请查看
references/useEditorContent.md

Components Reference

组件参考

RichText Component

RichText组件

The WebView component rendering the Tiptap editor.
Props:
  • editor
    : EditorBridge instance (required)
  • exclusivelyUseCustomOnMessage
    : Override internal onMessage handler (default: true)
Supports all standard React Native WebView props (not recommended unless necessary).
tsx
<RichText editor={editor} />
用于渲染Tiptap编辑器的WebView组件。
属性
  • editor
    :EditorBridge实例(必填)
  • exclusivelyUseCustomOnMessage
    :覆盖内部onMessage处理程序(默认值:true)
支持所有标准React Native WebView属性(非必要不推荐使用)。
tsx
<RichText editor={editor} />

Toolbar Component

Toolbar组件

Pre-built toolbar with context menus for headings and links, plus 20+ toolbar items.
Props:
  • editor
    : EditorBridge instance (required)
  • hidden
    : Control toolbar visibility
  • items
    : Array of ToolbarItem configurations (default: DEFAULT_TOOLBAR_ITEMS)
  • shouldHideDisabledToolbarItems
    : Hide disabled items instead of graying out (default: false)
Pre-built Toolbar Items:
  • Formatting: bold, italic, underline, strikethrough, code
  • Lists: bulletList, orderedList, checkList
  • Structure: quote, h1-h6
  • Links: link
  • History: undo, redo
  • Lists: lift, sink
tsx
<Toolbar
  editor={editor}
  hidden={!isKeyboardVisible}
  items={DEFAULT_TOOLBAR_ITEMS}
  shouldHideDisabledToolbarItems={true}
/>
预构建的工具栏,包含标题和链接的上下文菜单,以及20+工具栏项。
属性
  • editor
    :EditorBridge实例(必填)
  • hidden
    :控制工具栏可见性
  • items
    :ToolbarItem配置数组(默认值:DEFAULT_TOOLBAR_ITEMS)
  • shouldHideDisabledToolbarItems
    :隐藏禁用项而非灰显(默认值:false)
预构建工具栏项
  • 格式化:bold、italic、underline、strikethrough、code
  • 列表:bulletList、orderedList、checkList
  • 结构:quote、h1-h6
  • 链接:link
  • 历史记录:undo、redo
  • 列表:lift、sink
tsx
<Toolbar
  editor={editor}
  hidden={!isKeyboardVisible}
  items={DEFAULT_TOOLBAR_ITEMS}
  shouldHideDisabledToolbarItems={true}
/>

Custom Toolbar Items

自定义工具栏项

Create custom toolbar items with the ToolbarItem interface:
tsx
interface ToolbarItem {
  onPress: ({ editor, editorState }) => () => void;
  active: ({ editor, editorState }) => boolean;
  disabled: ({ editor, editorState }) => boolean;
  image: ({ editor, editorState }) => any;
}
See
references/Components.md
for complete component documentation and
references/CustomAndStaticToolbar/
for custom toolbar implementation examples.
使用ToolbarItem接口创建自定义工具栏项:
tsx
interface ToolbarItem {
  onPress: ({ editor, editorState }) => () => void;
  active: ({ editor, editorState }) => boolean;
  disabled: ({ editor, editorState }) => boolean;
  image: ({ editor, editorState }) => any;
}
完整组件文档请查看
references/Components.md
,自定义工具栏实现示例请查看
references/CustomAndStaticToolbar/

Bridge Extensions

桥接扩展

TenTap provides 19 pre-built BridgeExtensions covering standard rich text features:
TenTap提供19个预构建的BridgeExtension,覆盖所有标准富文本功能:

Core Extensions

核心扩展

  • CoreBridge: Document, paragraph, and text extensions
  • PlaceholderBridge: Placeholder text support
  • DropCursorBridge: Drag-and-drop cursor indicator
  • CoreBridge:文档、段落和文本扩展
  • PlaceholderBridge:占位符文本支持
  • DropCursorBridge:拖放光标指示器

Text Formatting

文本格式化

  • BoldBridge: Bold text formatting
  • ItalicBridge: Italic text formatting
  • UnderlineBridge: Underline text formatting
  • StrikeBridge: Strikethrough text formatting
  • CodeBridge: Inline code formatting
  • ColorBridge: Text color support
  • HighlightBridge: Text background highlighting
  • BoldBridge:粗体文本格式化
  • ItalicBridge:斜体文本格式化
  • UnderlineBridge:下划线文本格式化
  • StrikeBridge:删除线文本格式化
  • CodeBridge:行内代码格式化
  • ColorBridge:文本颜色支持
  • HighlightBridge:文本背景高亮

Structural Elements

结构元素

  • HeadingBridge: Heading levels 1-6
  • BlockquoteBridge: Blockquote blocks
  • BulletListBridge: Bulleted lists
  • OrderedListBridge: Numbered lists
  • TaskListBridge: Task/check lists
  • ListItemBridge: List indentation control (lift/sink)
  • HeadingBridge:1-6级标题
  • BlockquoteBridge:块引用
  • BulletListBridge:项目符号列表
  • OrderedListBridge:编号列表
  • TaskListBridge:任务/复选列表
  • ListItemBridge:列表缩进控制(lift/sink)

Media & Links

媒体与链接

  • ImageBridge: Image insertion and manipulation
  • LinkBridge: Hyperlink support
  • ImageBridge:图片插入与操作
  • LinkBridge:超链接支持

History

历史记录

  • HistoryBridge: Undo/redo functionality
  • HistoryBridge:撤销/重做功能

Configuring Extensions

配置扩展

Use
configureExtension
to customize Tiptap extension settings:
tsx
const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    PlaceholderBridge.configureExtension({
      placeholder: 'Type something amazing...',
    }),
    LinkBridge.configureExtension({
      openOnClick: false,
    }),
    HeadingBridge.configureExtension({
      levels: [1, 2, 3],
    }),
  ],
});
使用
configureExtension
自定义Tiptap扩展设置:
tsx
const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    PlaceholderBridge.configureExtension({
      placeholder: 'Type something amazing...',
    }),
    LinkBridge.configureExtension({
      openOnClick: false,
    }),
    HeadingBridge.configureExtension({
      levels: [1, 2, 3],
    }),
  ],
});

Extending Document Schema

扩展文档Schema

Use
extendExtension
to modify the document schema:
tsx
CoreBridge.extendExtension({
  content: 'heading block+',
});
This configures the document to require a heading as the first node.
See
references/BridgeExtensions.md
and
references/configureExtensions.md
for complete extension reference and configuration examples.
使用
extendExtension
修改文档Schema:
tsx
CoreBridge.extendExtension({
  content: 'heading block+',
});
此配置将文档设置为要求标题作为第一个节点。
完整扩展参考和配置示例请查看
references/BridgeExtensions.md
references/configureExtensions.md

Customization Guide

定制指南

Theming

主题定制

Apply custom themes to native components using the
theme
configuration:
tsx
const editor = useEditorBridge({
  theme: {
    toolbar: {
      toolbarBody: {
        backgroundColor: '#474747',
        borderTopColor: '#C6C6C6B3',
        borderBottomColor: '#C6C6C6B3',
      },
    },
    webview: {
      backgroundColor: '#1C1C1E',
    },
    webviewContainer: {},
  },
});
使用
theme
配置为原生组件应用自定义主题:
tsx
const editor = useEditorBridge({
  theme: {
    toolbar: {
      toolbarBody: {
        backgroundColor: '#474747',
        borderTopColor: '#C6C6C6B3',
        borderBottomColor: '#C6C6C6B3',
      },
    },
    webview: {
      backgroundColor: '#1C1C1E',
    },
    webviewContainer: {},
  },
});

Dark Mode

深色模式

Implement complete dark mode by combining native theme and web CSS:
tsx
import { darkEditorTheme, darkEditorCss } from '@10play/tentap-editor';

const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    CoreBridge.configureCSS(darkEditorCss),
  ],
  theme: darkEditorTheme,
});
See
references/darkTheme.md
and
references/DarkEditor.tsx
for complete dark mode implementation.
结合原生主题和Web CSS实现完整的深色模式:
tsx
import { darkEditorTheme, darkEditorCss } from '@10play/tentap-editor';

const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    CoreBridge.configureCSS(darkEditorCss),
  ],
  theme: darkEditorTheme,
});
完整的深色模式实现请查看
references/darkTheme.md
references/DarkEditor.tsx

Custom CSS

自定义CSS

Override or extend default CSS for any bridge extension:
tsx
const customCodeCSS = `
code {
  background-color: #ffdede;
  border-radius: 0.25em;
  color: #cd4242;
  padding: 0.25em;
}
`;

const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    CodeBridge.configureCSS(customCodeCSS),
  ],
});
覆盖或扩展任何桥接扩展的默认CSS:
tsx
const customCodeCSS = `
code {
  background-color: #ffdede;
  border-radius: 0.25em;
  color: #cd4242;
  padding: 0.25em;
}
`;

const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    CodeBridge.configureCSS(customCodeCSS),
  ],
});

Dynamic CSS Injection

动态CSS注入

Update CSS at runtime using the
injectCSS
method:
tsx
// Update bridge-specific CSS
editor.injectCSS(newCSS, CodeBridge.name);

// Add new stylesheet without overriding
editor.injectCSS(customCSS, 'custom-tag');
使用
injectCSS
方法在运行时更新CSS:
tsx
// 更新桥接专用CSS
editor.injectCSS(newCSS, CodeBridge.name);

// 添加新样式表而不覆盖原有样式
editor.injectCSS(customCSS, 'custom-tag');

Custom Fonts

自定义字体

Integrate custom fonts by converting to base64 and configuring via CSS:
  1. Convert font files using https://transfonter.org (check base64 option)
  2. Export the stylesheet.css as a TypeScript string
  3. Configure via CoreBridge CSS:
tsx
import { customFont } from './font';

const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    CoreBridge.configureCSS(customFont),
  ],
});
See
references/customCss.md
and
references/CustomCss.tsx
for complete CSS and font customization examples.
通过转换为base64并通过CSS配置来集成自定义字体:
  1. 使用https://transfonter.org转换字体文件(勾选base64选项)
  2. 将stylesheet.css导出为TypeScript字符串
  3. 通过CoreBridge CSS进行配置:
tsx
import { customFont } from './font';

const editor = useEditorBridge({
  bridgeExtensions: [
    ...TenTapStartKit,
    CoreBridge.configureCSS(customFont),
  ],
});
完整的CSS和字体定制示例请查看
references/customCss.md
references/CustomCss.tsx

Advanced Setup

高级设置

For custom Tiptap extensions or specialized editor behavior, use advanced setup with custom bundling.
对于自定义Tiptap扩展或专用编辑器行为,使用带自定义打包的高级设置。

Overview

概述

Advanced setup provides:
  • Full control over Tiptap extensions
  • Custom bridge implementations
  • Specialized editor configurations
  • Development server integration
高级设置提供:
  • 完全控制Tiptap扩展
  • 自定义桥接实现
  • 专用编辑器配置
  • 开发服务器集成

Process

流程

  1. Create editor-web directory: Separate folder for web editor code
  2. Configure TypeScript: Set up web-specific tsconfig.json
  3. Create editor files: index.html, AdvancedEditor.tsx, index.tsx
  4. Set up Vite: Configure bundler with module aliases
  5. Add build scripts: Package.json scripts for dev and production
  6. Import custom bundle: Use generated HTML with
    customSource
    prop
  1. 创建editor-web目录:存放Web编辑器代码的独立文件夹
  2. 配置TypeScript:设置Web专用的tsconfig.json
  3. 创建编辑器文件:index.html、AdvancedEditor.tsx、index.tsx
  4. 设置Vite:配置打包工具和模块别名
  5. 添加构建脚本:package.json中的开发和生产构建脚本
  6. 导入自定义包:使用生成的HTML作为
    customSource
    属性

Complete Example

完整示例

tsx
// editor-web/AdvancedEditor.tsx
import { EditorContent } from '@tiptap/react';
import { useTenTap, TenTapStartKit } from '@10play/tentap-editor';
import { CounterBridge } from '../CounterBridge';

export const AdvancedEditor = () => {
  const editor = useTenTap({
    bridges: [...TenTapStartKit, CounterBridge],
    tiptapOptions: {
      extensions: [Document, Paragraph, Text],
    },
  });

  return <EditorContent editor={editor} />;
};

// In React Native app
import { editorHtml } from './editor-web/build/editorHtml';

const editor = useEditorBridge({
  customSource: editorHtml,
  // ... other config
});
tsx
// editor-web/AdvancedEditor.tsx
import { EditorContent } from '@tiptap/react';
import { useTenTap, TenTapStartKit } from '@10play/tentap-editor';
import { CounterBridge } from '../CounterBridge';

export const AdvancedEditor = () => {
  const editor = useTenTap({
    bridges: [...TenTapStartKit, CounterBridge],
    tiptapOptions: {
      extensions: [Document, Paragraph, Text],
    },
  });

  return <EditorContent editor={editor} />;
};

// 在React Native应用中
import { editorHtml } from './editor-web/build/editorHtml';

const editor = useEditorBridge({
  customSource: editorHtml,
  // ... 其他配置
});

Creating Custom Bridges

创建自定义桥接

Implement custom bridge extensions for specialized functionality:
tsx
import { BridgeExtension } from '@10play/tentap-editor';
import { CharacterCount } from '@tiptap/extension-character-count';

export const CounterBridge = new BridgeExtension<
  typeof CharacterCount,
  { words: number; characters: number }
>({
  tiptapExtension: CharacterCount,
  extendEditorState: (editor) => ({
    words: editor.storage.characterCount.words(),
    characters: editor.storage.characterCount.characters(),
  }),
});
See
references/advancedSetup.md
and
references/Advanced/
for complete advanced setup instructions and working examples.
实现自定义桥接扩展以添加专用功能:
tsx
import { BridgeExtension } from '@10play/tentap-editor';
import { CharacterCount } from '@tiptap/extension-character-count';

export const CounterBridge = new BridgeExtension<
  typeof CharacterCount,
  { words: number; characters: number }
>({
  tiptapExtension: CharacterCount,
  extendEditorState: (editor) => ({
    words: editor.storage.characterCount.words(),
    characters: editor.storage.characterCount.characters(),
  }),
});
完整的高级设置说明和运行示例请查看
references/advancedSetup.md
references/Advanced/

Platform-Specific Considerations

平台特定注意事项

iOS Keyboard Handling

iOS键盘处理

When using React Navigation headers on iOS, configure
KeyboardAvoidingView
with proper offsets:
tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Platform } from 'react-native';

const HEADER_HEIGHT = 38;
const { top } = useSafeAreaInsets();
const keyboardVerticalOffset = HEADER_HEIGHT + top;

<KeyboardAvoidingView
  behavior="padding"
  keyboardVerticalOffset={Platform.OS === 'ios' ? keyboardVerticalOffset : undefined}
>
  <Toolbar editor={editor} />
</KeyboardAvoidingView>

// Add paddingBottom to RichText container on iOS
<View style={{ paddingBottom: Platform.OS === 'ios' ? HEADER_HEIGHT : 0 }}>
  <RichText editor={editor} />
</View>
See
references/navHeader.md
and
references/NavigationHeader.tsx
for complete iOS keyboard handling examples.
在iOS上使用React Navigation标题时,需配置
KeyboardAvoidingView
并设置正确的偏移量:
tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { Platform } from 'react-native';

const HEADER_HEIGHT = 38;
const { top } = useSafeAreaInsets();
const keyboardVerticalOffset = HEADER_HEIGHT + top;

<KeyboardAvoidingView
  behavior="padding"
  keyboardVerticalOffset={Platform.OS === 'ios' ? keyboardVerticalOffset : undefined}
>
  <Toolbar editor={editor} />
</KeyboardAvoidingView>

// 在iOS上为RichText容器添加paddingBottom
<View style={{ paddingBottom: Platform.OS === 'ios' ? HEADER_HEIGHT : 0 }}>
  <RichText editor={editor} />
</View>
完整的iOS键盘处理示例请查看
references/navHeader.md
references/NavigationHeader.tsx

Avoid iOS Keyboard Option

避免iOS键盘遮挡选项

The
avoidIosKeyboard
option helps keep the cursor visible when the editor is full-screen:
tsx
const editor = useEditorBridge({
  avoidIosKeyboard: true,  // Works on both iOS and Android
});
This automatically:
  • Adds bottom padding equal to keyboard height
  • Adjusts ProseMirror scroll threshold and margin
  • Ensures cursor remains visible during typing
avoidIosKeyboard
选项可帮助在全屏编辑器中保持光标可见:
tsx
const editor = useEditorBridge({
  avoidIosKeyboard: true,  // 同时支持iOS和Android
});
此选项会自动:
  • 添加与键盘高度相等的底部内边距
  • 调整ProseMirror的滚动阈值和边距
  • 确保在输入时光标保持可见

Example Patterns

示例模式

Basic Editor Setup

基础编辑器设置

File:
references/Basic.tsx
Demonstrates the simplest implementation with useEditorBridge, RichText, Toolbar, and KeyboardAvoidingView for keyboard-aware editing.
Key Concepts: Hook-based initialization, component composition, iOS keyboard handling, initial content setup
文件
references/Basic.tsx
展示了使用useEditorBridge、RichText、Toolbar和KeyboardAvoidingView实现的最简单编辑器,支持键盘感知编辑。
核心概念:基于钩子的初始化、组件组合、iOS键盘处理、初始内容设置

Dark Mode Editor

深色模式编辑器

File:
references/DarkEditor.tsx
Complete dark theme implementation combining
darkEditorTheme
native theme with
darkEditorCss
web styling, including conditional toolbar visibility based on keyboard and focus state.
Key Concepts: Theme configuration, CSS customization, state-driven UI, conditional rendering
文件
references/DarkEditor.tsx
结合
darkEditorTheme
原生主题和
darkEditorCss
Web样式的完整深色主题实现,包括基于键盘和聚焦状态的条件工具栏可见性。
核心概念:主题配置、CSS定制、状态驱动UI、条件渲染

Extension Configuration

扩展配置

File:
references/ConfigureExtentions.tsx
Shows how to configure PlaceholderBridge, LinkBridge, and DropCursorBridge with custom options, plus dynamic content manipulation and placeholder updates.
Key Concepts: Extension configuration, option customization, dynamic content updates
文件
references/ConfigureExtentions.tsx
展示如何使用自定义选项配置PlaceholderBridge、LinkBridge和DropCursorBridge,以及动态内容操作和占位符更新。
核心概念:扩展配置、选项定制、动态内容更新

Custom CSS Styling

自定义CSS样式

File:
references/CustomCss.tsx
Demonstrates CSS customization through bridge extensions, dynamic CSS injection using
injectCSS
, and targeting specific bridges with named tags.
Key Concepts: CSS configuration, dynamic styling, bridge-specific targeting
文件
references/CustomCss.tsx
展示通过桥接扩展进行CSS定制、使用
injectCSS
动态注入CSS,以及使用命名标签定位特定桥接。
核心概念:CSS配置、动态样式、桥接特定定位

React Navigation Integration

React Navigation集成

File:
references/NavigationHeader.tsx
Proper toolbar positioning with React Navigation headers using safe area insets and keyboard vertical offset calculation.
Key Concepts: Safe area handling, keyboard avoidance, platform-specific logic
文件
references/NavigationHeader.tsx
使用安全区域内边距和键盘垂直偏移计算,实现与React Navigation标题的正确工具栏定位。
核心概念:安全区域处理、键盘避免、平台特定逻辑

Custom Toolbar Implementation

自定义工具栏实现

Directory:
references/CustomAndStaticToolbar/
Build custom email composer interface with static always-visible toolbar and context-aware conditional toolbar, including state machine pattern for toolbar navigation and disabled state handling.
Key Concepts: Custom toolbar components, state management, conditional rendering, memoization
目录
references/CustomAndStaticToolbar/
构建自定义邮件撰写器界面,包含始终可见的静态工具栏和上下文感知的条件工具栏,包括用于工具栏导航和禁用状态处理的状态机模式。
核心概念:自定义工具栏组件、状态管理、条件渲染、记忆化

Chat Interface Pattern

聊天界面模式

File:
references/EditorStickToKeyboardExample.tsx
Chat-like interface with editor attached to keyboard, scrollable message list with WebView HTML rendering, and async content extraction.
Key Concepts: Keyboard avoidance, message rendering, content extraction, ScrollView management
文件
references/EditorStickToKeyboardExample.tsx
类似聊天的界面,编辑器附着在键盘上,可滚动的消息列表使用WebView渲染HTML,支持异步内容提取。
核心概念:键盘避免、消息渲染、内容提取、ScrollView管理

Advanced Rich Text Editor

高级富文本编辑器

File:
references/Advanced/AdvancedRichText.tsx
Advanced implementation with custom bridge extensions (CounterBridge), real-time word/character counting, bridge state consumption, and custom HTML source integration.
Key Concepts: Custom extensions, state management, computed values, custom source
文件
references/Advanced/AdvancedRichText.tsx
高级实现,包含自定义桥接扩展(CounterBridge)、实时字数/字符数统计、桥接状态消费和自定义HTML源集成。
核心概念:自定义扩展、状态管理、计算值、自定义源

Custom Bridge Extension

自定义桥接扩展

File:
references/Advanced/CounterBridge.ts
Complete example of creating custom BridgeExtension integrating Tiptap's CharacterCount extension, including TypeScript module augmentation for extending BridgeState and EditorBridge interfaces.
Key Concepts: Extension creation, type augmentation, storage access, computed state
文件
references/Advanced/CounterBridge.ts
创建自定义BridgeExtension的完整示例,集成Tiptap的CharacterCount扩展,包括用于扩展BridgeState和EditorBridge接口的TypeScript模块增强。
核心概念:扩展创建、类型增强、存储访问、计算状态

Advanced Web Setup

高级Web设置

Directory:
references/Advanced/editor-web/
Full advanced setup with Vite bundling, custom bridge integration, module aliasing for Tiptap compatibility, content injection timing workaround, and React 18 createRoot pattern.
Key Concepts: Custom bundling, Vite configuration, bridge composition, module resolution, development workflow
目录
references/Advanced/editor-web/
完整的高级设置,包含Vite打包、自定义桥接集成、Tiptap兼容的模块别名、内容注入时序解决方法和React 18 createRoot模式。
核心概念:自定义打包、Vite配置、桥接组合、模块解析、开发工作流

Resource References

资源参考

Documentation Files

文档文件

  • references/intro.md
    : Introduction, features, installation, basic usage
  • references/mainConcepts.md
    : Bridge architecture, simple vs advanced usage patterns
  • references/basic.md
    : Step-by-step basic editor tutorial
  • references/customTheme.md
    : Native theme customization guide
  • references/darkTheme.md
    : Dark mode implementation with theme + CSS
  • references/customCss.md
    : CSS and font customization, dynamic injection
  • references/configureExtensions.md
    : Extension configuration and schema extension
  • references/navHeader.md
    : iOS keyboard handling with React Navigation
  • references/advancedSetup.md
    : Complete advanced setup guide with Vite
  • references/intro.md
    :介绍、功能、安装、基础用法
  • references/mainConcepts.md
    :桥接架构、简单与高级使用模式
  • references/basic.md
    :分步基础编辑器教程
  • references/customTheme.md
    :原生主题定制指南
  • references/darkTheme.md
    :结合主题+CSS的深色模式实现
  • references/customCss.md
    :CSS和字体定制、动态注入
  • references/configureExtensions.md
    :扩展配置和Schema扩展
  • references/navHeader.md
    :React Navigation下的iOS键盘处理
  • references/advancedSetup.md
    :带Vite的完整高级设置指南

API References

API参考

  • references/EditorBridge.md
    : Complete EditorBridge interface with 30+ methods
  • references/BridgeExtensions.md
    : All 19 built-in extensions and configurations
  • references/BridgeState.md
    : BridgeState properties and useBridgeState hook
  • references/Components.md
    : RichText, Toolbar, and ToolbarItem components
  • references/useEditorBridge.md
    : Hook configuration options and usage
  • references/useEditorContent.md
    : Content retrieval hook with debouncing
  • references/EditorBridge.md
    :完整的EditorBridge接口(包含30+方法)
  • references/BridgeExtensions.md
    :所有19个内置扩展和配置
  • references/BridgeState.md
    :BridgeState属性和useBridgeState钩子
  • references/Components.md
    :RichText、Toolbar和ToolbarItem组件
  • references/useEditorBridge.md
    :钩子配置选项和用法
  • references/useEditorContent.md
    :带防抖的内容获取钩子

Example Source Code

示例源代码

Basic Examples:
  • Basic.tsx
    - Simple editor implementation
  • DarkEditor.tsx
    - Dark mode editor
  • ConfigureExtentions.tsx
    - Extension configuration
  • CustomCss.tsx
    - CSS customization
  • NavigationHeader.tsx
    - React Navigation integration
  • EditorStickToKeyboardExample.tsx
    - Chat interface pattern
Advanced Examples:
  • Advanced/AdvancedRichText.tsx
    - Advanced editor with custom extensions
  • Advanced/CounterBridge.ts
    - Custom bridge extension implementation
  • Advanced/editor-web/
    - Complete advanced setup with Vite
    • index.html
      - HTML template
    • AdvancedEditor.tsx
      - Web editor component
    • index.tsx
      - Entrypoint with content injection
    • tsconfig.json
      - TypeScript configuration
    • vite.config.ts
      - Vite bundler configuration
Custom Toolbar Examples:
  • CustomAndStaticToolbar/CustomAndStaticToolbar.tsx
    - Email composer with custom toolbars
  • CustomAndStaticToolbar/CustomRichText.tsx
    - Custom RichText wrapper
Utility Components:
  • Icon.tsx
    - Reusable SVG icon component
  • font.ts
    - Custom font definition (base64)
基础示例
  • Basic.tsx
    - 简单编辑器实现
  • DarkEditor.tsx
    - 深色模式编辑器
  • ConfigureExtentions.tsx
    - 扩展配置
  • CustomCss.tsx
    - CSS定制
  • NavigationHeader.tsx
    - React Navigation集成
  • EditorStickToKeyboardExample.tsx
    - 聊天界面模式
高级示例
  • Advanced/AdvancedRichText.tsx
    - 带自定义扩展的高级编辑器
  • Advanced/CounterBridge.ts
    - 自定义桥接扩展实现
  • Advanced/editor-web/
    - 带Vite的完整高级设置
    • index.html
      - HTML模板
    • AdvancedEditor.tsx
      - Web编辑器组件
    • index.tsx
      - 带内容注入的入口文件
    • tsconfig.json
      - TypeScript配置
    • vite.config.ts
      - Vite打包器配置
自定义工具栏示例
  • CustomAndStaticToolbar/CustomAndStaticToolbar.tsx
    - 带自定义工具栏的邮件撰写器
  • CustomAndStaticToolbar/CustomRichText.tsx
    - 自定义RichText包装器
工具组件
  • Icon.tsx
    - 可复用SVG图标组件
  • font.ts
    - 自定义字体定义(base64)

Best Practices

最佳实践

Performance Optimization

性能优化

  • Use
    useEditorContent
    instead of direct
    getHTML()
    calls for better performance
  • Implement debouncing for onChange handlers to reduce WebView-Native communication
  • Avoid unnecessary re-renders by memoizing toolbar items and custom components
  • Use
    avoidIosKeyboard
    option for better typing experience in full-screen editors
  • 使用
    useEditorContent
    替代直接调用
    getHTML()
    以获得更好的性能
  • 为onChange处理程序实现防抖,减少WebView与原生端的通信
  • 通过记忆化工具栏项和自定义组件避免不必要的重渲染
  • 在全屏编辑器中使用
    avoidIosKeyboard
    选项以获得更好的输入体验

State Management

状态管理

  • Leverage
    useBridgeState
    for reactive UI updates based on editor state
  • Use
    onChange
    callback with debouncing for auto-save functionality
  • Implement proper cleanup for custom bridges and extensions
  • 利用
    useBridgeState
    实现基于编辑器状态的响应式UI更新
  • 使用带防抖的onChange回调实现自动保存功能
  • 为自定义桥接和扩展实现适当的清理逻辑

Extension Organization

扩展组织

  • Spread
    TenTapStartKit
    before custom extensions to avoid duplication
  • Group related configurations in separate files for maintainability
  • Use TypeScript for type safety with custom bridges
  • 在自定义扩展之前展开
    TenTapStartKit
    以避免重复
  • 将相关配置分组到单独的文件中以提高可维护性
  • 为自定义桥接使用TypeScript以保证类型安全

Platform Considerations

平台考虑

  • Always test keyboard behavior on both iOS and Android
  • Configure
    keyboardVerticalOffset
    when using navigation headers
  • Use Platform-specific logic for platform-dependent features
  • Test safe area insets on devices with notches
  • 始终在iOS和Android上测试键盘行为
  • 使用导航标题时配置
    keyboardVerticalOffset
  • 为平台相关功能使用平台特定逻辑
  • 在带刘海的设备上测试安全区域内边距

Common Workflows

常见工作流

Creating a Chat Interface

创建聊天界面

Combine keyboard avoidance, message rendering, and content extraction for real-time chat applications. See
references/EditorStickToKeyboardExample.tsx
.
结合键盘避免、消息渲染和内容提取,构建实时聊天应用。请查看
references/EditorStickToKeyboardExample.tsx

Building an Email Composer

构建邮件撰写器

Implement custom toolbars, formatting controls, and conditional rendering for email composition. See
references/CustomAndStaticToolbar/
.
实现自定义工具栏、格式化控件和条件渲染,用于邮件撰写。请查看
references/CustomAndStaticToolbar/

Adding Dark Mode Support

添加深色模式支持

Integrate theme and CSS customization for complete dark mode implementation. See
references/DarkEditor.tsx
and
references/darkTheme.md
.
集成主题和CSS定制以实现完整的深色模式。请查看
references/DarkEditor.tsx
references/darkTheme.md

Creating Custom Extensions

创建自定义扩展

Extend editor functionality with custom bridge extensions and TypeScript augmentation. See
references/Advanced/CounterBridge.ts
and
references/Advanced/AdvancedRichText.tsx
.
通过自定义桥接扩展和TypeScript增强来扩展编辑器功能。请查看
references/Advanced/CounterBridge.ts
references/Advanced/AdvancedRichText.tsx

Implementing Auto-Save

实现自动保存

Use
useEditorContent
with debouncing for efficient content synchronization.
tsx
const content = useEditorContent(editor, { type: 'html' });

useEffect(() => {
  if (content) {
    debouncedSave(content);
  }
}, [content]);
使用带防抖的
useEditorContent
实现高效的内容同步。
tsx
const content = useEditorContent(editor, { type: 'html' });

useEffect(() => {
  if (content) {
    debouncedSave(content);
  }
}, [content]);

Additional Resources

额外资源