You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Plate富文本编辑器创建自定义插件(工具)

解决Plate富文本编辑器自定义元素工具栏按钮无效问题

核心问题

你使用了MarkToolbarButton来触发块级元素(Column)的插入,但这个组件是专门为**行内标记(如粗体、斜体)**设计的,不适用于块级元素。这就是点击按钮无反应的根本原因。

解决步骤

1. 替换工具栏组件(核心修复)

将MarkToolbarButton替换为块级元素专用的ElementToolbarButton,或者自定义按钮实现插入逻辑:

方式1:使用ElementToolbarButton(推荐)

如果你的模板提供了ElementToolbarButton组件,直接替换即可:

// fixed-toolbar-buttons.tsx
import { ElementToolbarButton } from '@udecode/plate-toolbar';
import { ELEMENT_COLUMN } from './columnsPlugin';

<ElementToolbarButton tooltip="双列布局" nodeType={ELEMENT_COLUMN}>
  <Icons.borderAll />
</ElementToolbarButton>

方式2:自定义插入按钮

如果没有ElementToolbarButton,可以通过useEditor钩子手动实现插入逻辑:

// fixed-toolbar-buttons.tsx
import { useEditor } from '@udecode/plate-common';
import { insertNodes } from '@udecode/plate-common';
import { ELEMENT_COLUMN } from './columnsPlugin';

const editor = useEditor();

const insertColumns = () => {
  // 插入预定义结构的双列元素,确保内部有可编辑的段落
  editor.insertNodes({
    type: ELEMENT_COLUMN,
    children: [
      { type: 'p', children: [{ text: '' }] },
      { type: 'p', children: [{ text: '' }] },
    ],
  });
};

<button onClick={insertColumns} title="双列布局" className="toolbar-button">
  <Icons.borderAll />
</button>

2. 完善插件的插入逻辑(可选)

可以在插件中添加快捷键或默认插入规则,增强可用性:

// columnsPlugin.tsx
import { createPluginFactory, insertNodes } from '@udecode/plate-common';
import { ColumnsElement } from '@/components/plate-ui/columns-element';

export const ELEMENT_COLUMN = 'column';

export const createColumnsPlugin = createPluginFactory({
  key: ELEMENT_COLUMN,
  isElement: true,
  component: ColumnsElement,
  handlers: {
    // 添加快捷键:Ctrl+Shift+C 插入双列布局
    onKeyDown: (editor, event) => {
      if (event.ctrlKey && event.shiftKey && event.key === 'C') {
        event.preventDefault();
        insertNodes(editor, {
          type: ELEMENT_COLUMN,
          children: [
            { type: 'p', children: [{ text: '' }] },
            { type: 'p', children: [{ text: '' }] },
          ],
        });
      }
    },
  },
});

3. 修复元素可编辑性

原代码中columns-wrapper设置了contentEditable={false},会导致整个双列区域无法编辑,需要调整结构:

// columns-element.tsx
import { cn, withRef } from '@udecode/cn';
import { PlateElement } from '@udecode/plate-common';
import { useFocused, useSelected } from 'slate-react';

import './column.scss';

export const ColumnsElement = withRef<typeof PlateElement>(
  ({ className, nodeProps, ...props }, ref) => {
    const { children } = props;
    const selected = useSelected();
    const focused = useFocused();

    // 将子节点拆分为两列,默认补空段落
    const [col1, col2] = Array.isArray(children) ? children : [children, { type: 'p', children: [{ text: '' }] }];

    return (
      <PlateElement 
        ref={ref} 
        {...props}
        className={cn(
          'columns-wrapper',
          selected && focused && 'ring-2 ring-ring ring-offset-2',
          className
        )}
      >
        <div className="column-block">{col1}</div>
        <div className="column-block">{col2}</div>
      </PlateElement>
    );
  }
);

关键说明

  • Mark vs Element:Plate中Mark对应行内格式,Element对应块级结构,两者的工具栏组件和处理逻辑完全不同,不能混用。
  • 节点结构:插入块级元素时,必须确保节点包含可编辑的子元素(如<p>),否则插入后无法输入内容。

内容的提问来源于stack exchange,提问作者Eshan Rajapakshe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:18:21