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

如何在Monaco Editor中添加自定义React组件作为覆盖小部件?

在Monaco Editor中集成自定义React覆盖小部件

问题描述

我尝试在Monaco Editor中添加自定义React组件作为覆盖小部件,希望该小部件像内置搜索小部件一样浮动显示在编辑器内容底部。我已能在应用中创建并渲染React组件,但不确定将其集成为Monaco覆盖小部件的最佳方式。

当前尝试代码

class MonacoInputQuickActionsWidget {
  domNode: HTMLDivElement;

  constructor(actionsHandler: MonacoInputQuickActions['onClick']) {
    this.domNode = document.createElement("div");
    this.domNode.className = "custom-widget";

    const widgetRoot = createRoot(this.domNode);

    widgetRoot.render(
      <MonacoInputQuickActions
        onClick={actionsHandler}
        className="absolute bottom-0.5 -right-1.5"
      />
    );
  }

  getId() {
    return "custom.widget";
  }

  getDomNode() {
    return this.domNode;
  }

  getPosition() {
    return {
      preference: monaco.editor.OverlayWidgetPositionPreference.BOTTOM_RIGHT_CORNER,
    };
  }
}

错误信息

m.createRoot is not a function
    at push../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/client.js.exports.createRoot

环境信息

  • React 18.3.1
  • Monaco Editor 0.50.0
  • Single-spa 微前端环境

解决方案

1. 修复createRoot导入问题

首先确认已正确从react-dom/client导入createRoot:

import { createRoot } from 'react-dom/client';

2. 兼容Single-spa环境的备选方案

如果导入后仍出现模块加载异常(Single-spa的模块隔离可能导致此问题),可以改用React 18兼容的legacy渲染方式:

import ReactDOM from 'react-dom';

class MonacoInputQuickActionsWidget {
  domNode: HTMLDivElement;

  constructor(actionsHandler: MonacoInputQuickActions['onClick']) {
    this.domNode = document.createElement("div");
    this.domNode.className = "custom-widget";

    ReactDOM.render(
      <MonacoInputQuickActions
        onClick={actionsHandler}
        className="absolute bottom-0.5 -right-1.5"
      />,
      this.domNode
    );
  }

  getId() {
    return "custom.widget";
  }

  getDomNode() {
    return this.domNode;
  }

  getPosition() {
    return {
      preference: monaco.editor.OverlayWidgetPositionPreference.BOTTOM_RIGHT_CORNER,
    };
  }
}

3. 正确注册覆盖小部件

确保在编辑器实例中完成小部件的注册:

// 假设已有editor实例
const editor = monaco.editor.create(document.getElementById('editor-container'), {
  // 编辑器配置项
});

// 创建并注册小部件
const actionsHandler = (action: string) => {
  // 自定义点击逻辑
};
const widget = new MonacoInputQuickActionsWidget(actionsHandler);
editor.addOverlayWidget(widget);

4. 样式优化

为了让小部件像内置搜索框一样贴合编辑器底部,调整CSS样式:

.custom-widget {
  position: absolute;
  bottom: 0;
  padding: 8px 16px;
  background: #fff;
  border-top: 1px solid #e0e0e0;
  /* 根据需求添加其他样式 */
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:00:53