diff --git a/common/changes/@coze-editor/preset-chat/feature-add-refresh-draw-selection_2026-07-15-09-30.json b/common/changes/@coze-editor/preset-chat/feature-add-refresh-draw-selection_2026-07-15-09-30.json
new file mode 100644
index 00000000..01d2f092
--- /dev/null
+++ b/common/changes/@coze-editor/preset-chat/feature-add-refresh-draw-selection_2026-07-15-09-30.json
@@ -0,0 +1,11 @@
+{
+ "changes": [
+ {
+ "packageName": "@coze-editor/preset-chat",
+ "comment": "add editor.refreshDrawSelection",
+ "type": "minor"
+ }
+ ],
+ "packageName": "@coze-editor/preset-chat",
+ "email": "stream-pipe@users.noreply.github.com"
+}
diff --git a/packages/text-editor/dev/src/index.tsx b/packages/text-editor/dev/src/index.tsx
index 45ad0ee8..0ee94c86 100644
--- a/packages/text-editor/dev/src/index.tsx
+++ b/packages/text-editor/dev/src/index.tsx
@@ -1,5 +1,5 @@
import { createRoot } from 'react-dom/client';
-import Page from './pages/prefix';
+import Page from './pages/chat';
import './index.css';
createRoot(document.getElementById('app')!).render();
diff --git a/packages/text-editor/dev/src/pages/chat/elements.tsx b/packages/text-editor/dev/src/pages/chat/elements.tsx
index eb1cfbb2..ec4d51dc 100644
--- a/packages/text-editor/dev/src/pages/chat/elements.tsx
+++ b/packages/text-editor/dev/src/pages/chat/elements.tsx
@@ -1,7 +1,7 @@
import { EditorAPI, useCurrentElement } from '@coze-editor/editor/preset-chat';
import { useEditor } from '@coze-editor/editor/react';
import { Popover } from '@douyinfe/semi-ui';
-import { SVGProps, useContext } from 'react';
+import { SVGProps, useContext, useEffect } from 'react';
import { UploadingContext } from './upload';
function GravityUiCode(props: SVGProps) {
@@ -117,7 +117,15 @@ function LineMdUploadingLoop(props: SVGProps) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function UploadFile({ filename, array }: { filename: string; array: any[] }) {
const uploading = useContext(UploadingContext)
+ const editor = useEditor();
console.log('array', array)
+
+ useEffect(() => {
+ if (uploading === false) {
+ editor?.refreshDrawSelection();
+ }
+ }, [uploading])
+
return
diff --git a/packages/text-editor/dev/src/pages/chat/index.tsx b/packages/text-editor/dev/src/pages/chat/index.tsx
index efebec4b..4162cf91 100644
--- a/packages/text-editor/dev/src/pages/chat/index.tsx
+++ b/packages/text-editor/dev/src/pages/chat/index.tsx
@@ -1,7 +1,7 @@
import preset, { schemaUtils, type EditorAPI } from '@coze-editor/editor/preset-chat'
import { type EditorAPI as CodeEditorAPI } from '@coze-editor/editor/preset-code'
import { EditorProvider, PositionMirror, Renderer, useEditor, useMouseSelectionPopup } from '@coze-editor/editor/react'
-import { EditorView } from '@codemirror/view'
+import { drawSelection, EditorView } from '@codemirror/view'
import { useRef, useState } from 'react'
import { Extension } from '@codemirror/state';
import { astDebugger } from '@coze-editor/editor';
@@ -15,6 +15,7 @@ import { UploadContext, UploadFile } from './upload'
const extensions: Extension[] = [
astDebugger,
EditorView.lineWrapping,
+ drawSelection(),
];
const defaultValue = schemaUtils.fromJSON([
diff --git a/packages/text-editor/dev/src/pages/chat/upload.tsx b/packages/text-editor/dev/src/pages/chat/upload.tsx
index f3e31b25..3505a391 100644
--- a/packages/text-editor/dev/src/pages/chat/upload.tsx
+++ b/packages/text-editor/dev/src/pages/chat/upload.tsx
@@ -20,7 +20,7 @@ function UploadFile() {
editor.insertElement({
tagName: 'upload',
attributes: {
- filename: 'my.pdf',
+ filename: 'myloooooooooooooooongpdf.pdf',
array: [
{ foo: 1 },
true,
@@ -29,6 +29,8 @@ function UploadFile() {
},
})
+ editor.focus()
+
await delay(2000)
setUploading(false)
diff --git a/packages/text-editor/preset-chat/src/plugins.ts b/packages/text-editor/preset-chat/src/plugins.ts
index c24d670d..d1557741 100644
--- a/packages/text-editor/preset-chat/src/plugins.ts
+++ b/packages/text-editor/preset-chat/src/plugins.ts
@@ -47,6 +47,16 @@ function insertElement({ view }: { view: EditorView }) {
};
}
+// 如果用了 drawSelection 且 widget 内的 React 组件宽度发生变化,光标位置会异常
+// 原因:drawSelection 感知不到 react 组件渲染导致的光标位置变化,需手动通知
+function refreshDrawSelection({ view }: { view: EditorView }) {
+ return () => {
+ view.dispatch({
+ selection: view.state.selection,
+ });
+ };
+}
+
const plugins = [
extension([
focusedField,
@@ -60,6 +70,7 @@ const plugins = [
chatExtension(),
]),
api('insertElement', insertElement),
+ api('refreshDrawSelection', refreshDrawSelection),
option('elements', (elements: ElementsDefinition) =>
elementsFacet.of(elements),
),