自定义插件
插件架构
每个插件是一个目录,包含 index.ts 导出:
typescript
// app/frontend/modules/content/editor/plugins/my-plugin/index.ts
import { createPlugin } from '../factory'
export const myPlugin = createPlugin({
id: 'my-plugin',
name: 'My Plugin',
version: '1.0.0',
toolbarItems: [
{ id: 'my-plugin', icon: MyIcon, label: 'My Plugin', group: 'insert' },
],
commands: {
'my-plugin': (context) => {
// 执行逻辑
},
},
shortcuts: {
'ctrl+shift+x': 'my-plugin',
},
})
export { MyPluginComponent } from './MyPluginComponent'创建插件步骤
- 创建目录
app/frontend/modules/content/editor/plugins/my-plugin/ - 创建
index.ts导出插件定义 - 在
RichTextEditor.tsx中注册插件 - 在
plugins/index.ts中导出
DecoratorNode
对于需要在编辑器中渲染 React 组件的插件,使用 Lexical 的 DecoratorNode:
typescript
import { DecoratorNode } from 'lexical'
export class MyNode extends DecoratorNode<React.ReactNode> {
static getType() { return 'my-node' }
static clone(node) { return new MyNode(node.__data, node.__key) }
createDOM() { return document.createElement('div') }
updateDOM() { return false }
decorate() {
return <MyComponent data={this.__data} />
}
exportJSON() {
return { type: 'my-node', version: 1, data: this.__data }
}
static importJSON(serializedNode) {
return new MyNode(serializedNode.data)
}
}插件接口
typescript
interface Plugin {
id: string
name: string
version: string
init?: (context: PluginContext) => void
destroy?: () => void
getToolbarItems?: () => ToolbarItem[]
getCommands?: () => Record<string, (context: PluginContext, payload?: any) => void>
getShortcuts?: () => Record<string, string>
getNodes?: () => Array<typeof DecoratorNode>
}示例:Mermaid 插件
typescript
// app/frontend/modules/content/editor/plugins/mermaid/index.ts
import { createPlugin } from '../factory'
import { MermaidNode } from './MermaidNode'
export const mermaidPlugin = createPlugin({
id: 'mermaid',
name: 'Mermaid',
version: '1.0.0',
toolbarItems: [
{ id: 'mermaid', icon: MermaidIcon, label: 'Mermaid 图表', group: 'insert' },
],
commands: {
'mermaid': (context, payload) => {
const node = new MermaidNode(payload?.code || '')
$insertNodes([node])
},
},
getNodes: () => [MermaidNode],
})