@ant-design/agentic-ui 2.27.1 → 2.27.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,6 @@ import type { BubbleProps } from './type';
24
24
  * @param {any[]} [props.deps] - 依赖数组
25
25
  * @param {MutableRefObject} [props.bubbleRef] - 气泡引用
26
26
  * @param {MessageBubbleData} [props.originData] - 消息数据,包含角色信息
27
- *
28
27
  * @example
29
28
  * ```tsx
30
29
  * // 用户消息会自动使用 UserBubble
@@ -38,6 +37,13 @@ import type { BubbleProps } from './type';
38
37
  * originData={{ role: 'assistant', content: '你好!有什么可以帮助你的吗?' }}
39
38
  * avatar={{ avatar: "ai.jpg", title: "AI助手" }}
40
39
  * />
40
+ *
41
+ * // Schema Editor 在开发环境下自动启用
42
+ * // 需要传入 id 以支持插件识别
43
+ * <Bubble
44
+ * id="msg-1"
45
+ * originData={{ id: 'msg-1', role: 'assistant', originContent: '# Hello' }}
46
+ * />
41
47
  * ```
42
48
  *
43
49
  * @returns {React.ReactElement} 渲染的聊天气泡组件
@@ -51,8 +51,9 @@ function _object_spread_props(target, source) {
51
51
  return target;
52
52
  }
53
53
  import { memo } from "react";
54
- import React, { useMemo } from "react";
54
+ import React from "react";
55
55
  import { AIBubble } from "./AIBubble";
56
+ import { useSchemaEditorBridge } from "./schema-editor";
56
57
  import { UserBubble } from "./UserBubble";
57
58
  /**
58
59
  * Bubble 组件 - 聊天气泡组件(智能分发器)
@@ -77,7 +78,6 @@ import { UserBubble } from "./UserBubble";
77
78
  * @param {any[]} [props.deps] - 依赖数组
78
79
  * @param {MutableRefObject} [props.bubbleRef] - 气泡引用
79
80
  * @param {MessageBubbleData} [props.originData] - 消息数据,包含角色信息
80
- *
81
81
  * @example
82
82
  * ```tsx
83
83
  * // 用户消息会自动使用 UserBubble
@@ -91,25 +91,30 @@ import { UserBubble } from "./UserBubble";
91
91
  * originData={{ role: 'assistant', content: '你好!有什么可以帮助你的吗?' }}
92
92
  * avatar={{ avatar: "ai.jpg", title: "AI助手" }}
93
93
  * />
94
+ *
95
+ * // Schema Editor 在开发环境下自动启用
96
+ * // 需要传入 id 以支持插件识别
97
+ * <Bubble
98
+ * id="msg-1"
99
+ * originData={{ id: 'msg-1', role: 'assistant', originContent: '# Hello' }}
100
+ * />
94
101
  * ```
95
102
  *
96
103
  * @returns {React.ReactElement} 渲染的聊天气泡组件
97
104
  */ export var Bubble = /*#__PURE__*/ memo(function(props) {
98
- var _props_originData;
99
- // 根据角色自动选择组件
100
- var isUserMessage = useMemo(function() {
101
- if (props.placement === undefined) {
102
- var _props_originData;
103
- return ((_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.role) === 'user';
104
- }
105
- return props.placement === 'right';
106
- }, [
107
- props.placement,
108
- (_props_originData = props.originData) === null || _props_originData === void 0 ? void 0 : _props_originData.role
109
- ]);
110
- // 自动设置正确的 placement,确保类型安全
111
- var bubbleProps = _object_spread_props(_object_spread({}, props), {
112
- placement: props.placement || (isUserMessage ? 'right' : 'left')
105
+ var originData = props.originData;
106
+ /** 判断是否有可编辑的字符串内容 */ var hasEditableContent = !!(originData === null || originData === void 0 ? void 0 : originData.originContent) || typeof (originData === null || originData === void 0 ? void 0 : originData.content) === 'string';
107
+ /** 获取初始内容:优先 originContent,回退到字符串 content */ var initialContent = hasEditableContent ? (originData === null || originData === void 0 ? void 0 : originData.originContent) || (originData === null || originData === void 0 ? void 0 : originData.content) : '';
108
+ /**
109
+ * Schema Editor Bridge Hook
110
+ * @description 开发环境自动启用,生产环境返回原始内容
111
+ */ var content = useSchemaEditorBridge(props.id, initialContent).content;
112
+ /** 根据角色自动选择组件 */ var isUserMessage = props.placement === undefined ? (originData === null || originData === void 0 ? void 0 : originData.role) === 'user' : props.placement === 'right';
113
+ /** 构建传递给子组件的 props */ var bubbleProps = _object_spread_props(_object_spread({}, props), {
114
+ placement: props.placement || (isUserMessage ? 'right' : 'left'),
115
+ originData: originData ? _object_spread({}, originData, hasEditableContent && {
116
+ content: content
117
+ }) : undefined
113
118
  });
114
119
  // 根据角色分发到对应的子组件
115
120
  if (isUserMessage) {
@@ -12,3 +12,5 @@ export { PureAIBubble, PureBubble, PureUserBubble } from './PureBubble';
12
12
  export * from './MessagesContent/BubbleContext';
13
13
  export * from './type';
14
14
  export { UserBubble } from './UserBubble';
15
+ /** Schema Editor 相关导出 */
16
+ export * from './schema-editor';
@@ -11,3 +11,4 @@ export { PureAIBubble, PureBubble, PureUserBubble } from "./PureBubble";
11
11
  export * from "./MessagesContent/BubbleContext";
12
12
  export * from "./type";
13
13
  export { UserBubble } from "./UserBubble";
14
+ /** Schema Editor 相关导出 */ export * from "./schema-editor";
@@ -0,0 +1,106 @@
1
+ import type { SchemaValue } from '@schema-editor/host-sdk/core';
2
+ /**
3
+ * Bubble 处理器接口
4
+ * @description 每个 Bubble 组件注册时提供的处理器
5
+ */
6
+ export interface BubbleHandler {
7
+ /** 获取当前内容 */
8
+ getContent: () => string;
9
+ /** 设置内容 */
10
+ setContent: (content: string) => void;
11
+ /** 自定义预览渲染(可选) */
12
+ renderPreview?: (schema: SchemaValue, containerId: string) => (() => void) | void;
13
+ }
14
+ /**
15
+ * Schema Editor Bridge 单例管理器
16
+ * @description 全局唯一的监听器管理,避免多个 Bubble 组件冲突
17
+ *
18
+ * @remarks
19
+ * 推荐使用 `useSchemaEditorBridge` Hook,它会自动管理启用状态和注册/注销流程。
20
+ * Schema Editor 在开发环境下自动启用(process.env.NODE_ENV === 'development')。
21
+ * 如需直接使用 Manager,需手动调用 `setEnabled(true)` 启动 Bridge。
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * // 推荐方式:使用 useSchemaEditorBridge Hook(开发环境自动启用)
26
+ * const { content, setContent } = useSchemaEditorBridge(id, initialContent);
27
+ *
28
+ * // 直接使用 Manager(需手动管理启用状态)
29
+ * useEffect(() => {
30
+ * const manager = SchemaEditorBridgeManager.getInstance();
31
+ * manager.setEnabled(true); // 必须:启用 Bridge
32
+ * manager.register(id, {
33
+ * getContent: () => contentRef.current,
34
+ * setContent: (c) => setContent(c)
35
+ * });
36
+ * return () => manager.unregister(id);
37
+ * }, [id]);
38
+ * ```
39
+ */
40
+ export declare class SchemaEditorBridgeManager {
41
+ /** 单例实例 */
42
+ private static instance;
43
+ /** Bubble 处理器注册表:id -> handler */
44
+ private registry;
45
+ /** Bridge 清理函数 */
46
+ private cleanup;
47
+ /** 是否启用 */
48
+ private enabled;
49
+ /** 预览 Root */
50
+ private previewRoot;
51
+ /** 当前正在编辑的 Bubble id */
52
+ private currentEditingId;
53
+ /** 私有构造函数,防止外部实例化 */
54
+ private constructor();
55
+ /**
56
+ * 获取单例实例
57
+ * @returns SchemaEditorBridgeManager 实例
58
+ */
59
+ static getInstance(): SchemaEditorBridgeManager;
60
+ /**
61
+ * 设置启用状态
62
+ * @param enabled - 是否启用
63
+ */
64
+ setEnabled(enabled: boolean): void;
65
+ /**
66
+ * 检查是否启用
67
+ */
68
+ isEnabled(): boolean;
69
+ /**
70
+ * 注册 Bubble 处理器
71
+ * @param id - Bubble 的唯一标识(data-id)
72
+ * @param handler - 处理器对象
73
+ */
74
+ register(id: string, handler: BubbleHandler): void;
75
+ /**
76
+ * 注销 Bubble 处理器
77
+ * @param id - Bubble 的唯一标识
78
+ */
79
+ unregister(id: string): void;
80
+ /**
81
+ * 获取注册的 Bubble 数量
82
+ */
83
+ getRegistrySize(): number;
84
+ /**
85
+ * 检查某个 ID 是否已注册
86
+ */
87
+ has(id: string): boolean;
88
+ /**
89
+ * 启动 Bridge(幂等,已启动时直接返回)
90
+ */
91
+ private startBridge;
92
+ /**
93
+ * 停止 Bridge
94
+ */
95
+ private stopBridge;
96
+ /**
97
+ * 创建默认预览
98
+ * @description 使用 MarkdownEditor 渲染 Markdown 预览
99
+ */
100
+ private createDefaultPreview;
101
+ /**
102
+ * 销毁单例(主要用于测试)
103
+ */
104
+ static destroy(): void;
105
+ }
106
+ export default SchemaEditorBridgeManager;
@@ -0,0 +1,257 @@
1
+ function _class_call_check(instance, Constructor) {
2
+ if (!(instance instanceof Constructor)) {
3
+ throw new TypeError("Cannot call a class as a function");
4
+ }
5
+ }
6
+ function _defineProperties(target, props) {
7
+ for(var i = 0; i < props.length; i++){
8
+ var descriptor = props[i];
9
+ descriptor.enumerable = descriptor.enumerable || false;
10
+ descriptor.configurable = true;
11
+ if ("value" in descriptor) descriptor.writable = true;
12
+ Object.defineProperty(target, descriptor.key, descriptor);
13
+ }
14
+ }
15
+ function _create_class(Constructor, protoProps, staticProps) {
16
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
17
+ if (staticProps) _defineProperties(Constructor, staticProps);
18
+ return Constructor;
19
+ }
20
+ function _define_property(obj, key, value) {
21
+ if (key in obj) {
22
+ Object.defineProperty(obj, key, {
23
+ value: value,
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true
27
+ });
28
+ } else {
29
+ obj[key] = value;
30
+ }
31
+ return obj;
32
+ }
33
+ import { createSchemaEditorBridge } from "@schema-editor/host-sdk/core";
34
+ import React from "react";
35
+ import ReactDOM from "react-dom/client";
36
+ import { MarkdownEditor } from "../../MarkdownEditor";
37
+ /**
38
+ * Schema Editor Bridge 单例管理器
39
+ * @description 全局唯一的监听器管理,避免多个 Bubble 组件冲突
40
+ *
41
+ * @remarks
42
+ * 推荐使用 `useSchemaEditorBridge` Hook,它会自动管理启用状态和注册/注销流程。
43
+ * Schema Editor 在开发环境下自动启用(process.env.NODE_ENV === 'development')。
44
+ * 如需直接使用 Manager,需手动调用 `setEnabled(true)` 启动 Bridge。
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * // 推荐方式:使用 useSchemaEditorBridge Hook(开发环境自动启用)
49
+ * const { content, setContent } = useSchemaEditorBridge(id, initialContent);
50
+ *
51
+ * // 直接使用 Manager(需手动管理启用状态)
52
+ * useEffect(() => {
53
+ * const manager = SchemaEditorBridgeManager.getInstance();
54
+ * manager.setEnabled(true); // 必须:启用 Bridge
55
+ * manager.register(id, {
56
+ * getContent: () => contentRef.current,
57
+ * setContent: (c) => setContent(c)
58
+ * });
59
+ * return () => manager.unregister(id);
60
+ * }, [id]);
61
+ * ```
62
+ */ export var SchemaEditorBridgeManager = /*#__PURE__*/ function() {
63
+ "use strict";
64
+ function SchemaEditorBridgeManager() {
65
+ _class_call_check(this, SchemaEditorBridgeManager);
66
+ /** Bubble 处理器注册表:id -> handler */ _define_property(this, "registry", new Map());
67
+ /** Bridge 清理函数 */ _define_property(this, "cleanup", null);
68
+ /** 是否启用 */ _define_property(this, "enabled", false);
69
+ /** 预览 Root */ _define_property(this, "previewRoot", null);
70
+ /** 当前正在编辑的 Bubble id */ _define_property(this, "currentEditingId", null);
71
+ }
72
+ _create_class(SchemaEditorBridgeManager, [
73
+ {
74
+ /**
75
+ * 设置启用状态
76
+ * @param enabled - 是否启用
77
+ */ key: "setEnabled",
78
+ value: function setEnabled(enabled) {
79
+ var wasEnabled = this.enabled;
80
+ this.enabled = enabled;
81
+ if (enabled && !wasEnabled && this.registry.size > 0) {
82
+ this.startBridge();
83
+ } else if (!enabled && wasEnabled) {
84
+ this.stopBridge();
85
+ }
86
+ }
87
+ },
88
+ {
89
+ /**
90
+ * 检查是否启用
91
+ */ key: "isEnabled",
92
+ value: function isEnabled() {
93
+ return this.enabled;
94
+ }
95
+ },
96
+ {
97
+ /**
98
+ * 注册 Bubble 处理器
99
+ * @param id - Bubble 的唯一标识(data-id)
100
+ * @param handler - 处理器对象
101
+ */ key: "register",
102
+ value: function register(id, handler) {
103
+ this.registry.set(id, handler);
104
+ if (this.enabled) {
105
+ this.startBridge();
106
+ }
107
+ }
108
+ },
109
+ {
110
+ /**
111
+ * 注销 Bubble 处理器
112
+ * @param id - Bubble 的唯一标识
113
+ */ key: "unregister",
114
+ value: function unregister(id) {
115
+ this.registry.delete(id);
116
+ if (this.registry.size === 0) {
117
+ this.stopBridge();
118
+ }
119
+ }
120
+ },
121
+ {
122
+ /**
123
+ * 获取注册的 Bubble 数量
124
+ */ key: "getRegistrySize",
125
+ value: function getRegistrySize() {
126
+ return this.registry.size;
127
+ }
128
+ },
129
+ {
130
+ /**
131
+ * 检查某个 ID 是否已注册
132
+ */ key: "has",
133
+ value: function has(id) {
134
+ return this.registry.has(id);
135
+ }
136
+ },
137
+ {
138
+ key: "startBridge",
139
+ value: /**
140
+ * 启动 Bridge(幂等,已启动时直接返回)
141
+ */ function startBridge() {
142
+ var _this = this;
143
+ if (this.cleanup) return;
144
+ this.cleanup = createSchemaEditorBridge({
145
+ getSchema: function(params) {
146
+ var handler = _this.registry.get(params);
147
+ if (!handler) {
148
+ // 返回 undefined 表示该元素不可编辑,插件将无法打开编辑器
149
+ _this.currentEditingId = null;
150
+ return undefined;
151
+ }
152
+ // 记录当前编辑的 Bubble id,供 renderPreview 使用
153
+ _this.currentEditingId = params;
154
+ return handler.getContent();
155
+ },
156
+ updateSchema: function(schema, params) {
157
+ var handler = _this.registry.get(params);
158
+ if (!handler) {
159
+ return false;
160
+ }
161
+ try {
162
+ var content = typeof schema === 'string' ? schema : JSON.stringify(schema, null, 2);
163
+ handler.setContent(content);
164
+ return true;
165
+ } catch (error) {
166
+ console.error('[SchemaEditorBridge] updateSchema failed:', error);
167
+ return false;
168
+ }
169
+ },
170
+ renderPreview: function(schema, containerId) {
171
+ /** 使用当前编辑 Bubble 的自定义预览 */ if (_this.currentEditingId) {
172
+ var handler = _this.registry.get(_this.currentEditingId);
173
+ if (handler === null || handler === void 0 ? void 0 : handler.renderPreview) {
174
+ return handler.renderPreview(schema, containerId);
175
+ }
176
+ }
177
+ /** 兜底:内置 Markdown 预览 */ return _this.createDefaultPreview(schema, containerId);
178
+ }
179
+ });
180
+ }
181
+ },
182
+ {
183
+ key: "stopBridge",
184
+ value: /**
185
+ * 停止 Bridge
186
+ */ function stopBridge() {
187
+ if (this.cleanup) {
188
+ this.cleanup();
189
+ this.cleanup = null;
190
+ }
191
+ }
192
+ },
193
+ {
194
+ key: "createDefaultPreview",
195
+ value: /**
196
+ * 创建默认预览
197
+ * @description 使用 MarkdownEditor 渲染 Markdown 预览
198
+ */ function createDefaultPreview(schema, containerId) {
199
+ var _this = this;
200
+ var container = document.getElementById(containerId);
201
+ if (!container) return;
202
+ var content = typeof schema === 'string' ? schema : JSON.stringify(schema, null, 2);
203
+ /** 复用或创建 Root */ if (!this.previewRoot) {
204
+ this.previewRoot = ReactDOM.createRoot(container);
205
+ }
206
+ this.previewRoot.render(React.createElement(MarkdownEditor, {
207
+ initValue: content,
208
+ readonly: true,
209
+ style: {
210
+ padding: 16
211
+ },
212
+ height: 'auto',
213
+ width: '100%'
214
+ }));
215
+ return function() {
216
+ if (_this.previewRoot) {
217
+ _this.previewRoot.unmount();
218
+ _this.previewRoot = null;
219
+ }
220
+ };
221
+ }
222
+ }
223
+ ], [
224
+ {
225
+ key: "getInstance",
226
+ value: /**
227
+ * 获取单例实例
228
+ * @returns SchemaEditorBridgeManager 实例
229
+ */ function getInstance() {
230
+ if (!SchemaEditorBridgeManager.instance) {
231
+ SchemaEditorBridgeManager.instance = new SchemaEditorBridgeManager();
232
+ }
233
+ return SchemaEditorBridgeManager.instance;
234
+ }
235
+ },
236
+ {
237
+ key: "destroy",
238
+ value: /**
239
+ * 销毁单例(主要用于测试)
240
+ */ function destroy() {
241
+ if (SchemaEditorBridgeManager.instance) {
242
+ SchemaEditorBridgeManager.instance.stopBridge();
243
+ SchemaEditorBridgeManager.instance.registry.clear();
244
+ SchemaEditorBridgeManager.instance.currentEditingId = null;
245
+ /** 清理预览 Root */ if (SchemaEditorBridgeManager.instance.previewRoot) {
246
+ SchemaEditorBridgeManager.instance.previewRoot.unmount();
247
+ SchemaEditorBridgeManager.instance.previewRoot = null;
248
+ }
249
+ SchemaEditorBridgeManager.instance = null;
250
+ }
251
+ }
252
+ }
253
+ ]);
254
+ return SchemaEditorBridgeManager;
255
+ }();
256
+ /** 单例实例 */ _define_property(SchemaEditorBridgeManager, "instance", null);
257
+ export default SchemaEditorBridgeManager;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Schema Editor 模块导出
3
+ * @description 包含 Schema Editor 插件集成相关的所有功能
4
+ */
5
+ export { SchemaEditorBridgeManager, type BubbleHandler, } from './SchemaEditorBridgeManager';
6
+ export { useSchemaEditorBridge, type UseSchemaEditorBridgeResult, } from './useSchemaEditorBridge';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Schema Editor 模块导出
3
+ * @description 包含 Schema Editor 插件集成相关的所有功能
4
+ */ export { SchemaEditorBridgeManager } from "./SchemaEditorBridgeManager";
5
+ export { useSchemaEditorBridge } from "./useSchemaEditorBridge";
@@ -0,0 +1,23 @@
1
+ import { MutableRefObject } from 'react';
2
+ /**
3
+ * useRefState - 同时维护 state 和 ref 的 hook
4
+ * @description 解决 setState 后立即读取 ref 得到旧值的问题
5
+ *
6
+ * @param initialValue - 初始值
7
+ * @returns [state, setState, ref] - state 用于渲染,setState 同步更新 ref,ref 用于回调
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const [content, setContent, contentRef] = useRefState('');
12
+ *
13
+ * const handler = {
14
+ * getContent: () => contentRef.current, // 始终是最新值
15
+ * setContent: (val) => {
16
+ * setContent(val); // 立即更新 ref
17
+ * // 此时 contentRef.current 已经是新值了
18
+ * }
19
+ * };
20
+ * ```
21
+ */
22
+ export declare function useRefState<T>(initialValue: T): [T, (value: T | ((prev: T) => T)) => void, MutableRefObject<T>];
23
+ export default useRefState;
@@ -0,0 +1,83 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function _iterable_to_array_limit(arr, i) {
10
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
11
+ if (_i == null) return;
12
+ var _arr = [];
13
+ var _n = true;
14
+ var _d = false;
15
+ var _s, _e;
16
+ try {
17
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
18
+ _arr.push(_s.value);
19
+ if (i && _arr.length === i) break;
20
+ }
21
+ } catch (err) {
22
+ _d = true;
23
+ _e = err;
24
+ } finally{
25
+ try {
26
+ if (!_n && _i["return"] != null) _i["return"]();
27
+ } finally{
28
+ if (_d) throw _e;
29
+ }
30
+ }
31
+ return _arr;
32
+ }
33
+ function _non_iterable_rest() {
34
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
35
+ }
36
+ function _sliced_to_array(arr, i) {
37
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
38
+ }
39
+ function _unsupported_iterable_to_array(o, minLen) {
40
+ if (!o) return;
41
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
42
+ var n = Object.prototype.toString.call(o).slice(8, -1);
43
+ if (n === "Object" && o.constructor) n = o.constructor.name;
44
+ if (n === "Map" || n === "Set") return Array.from(n);
45
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
+ }
47
+ import { useState, useRef, useCallback } from "react";
48
+ /**
49
+ * useRefState - 同时维护 state 和 ref 的 hook
50
+ * @description 解决 setState 后立即读取 ref 得到旧值的问题
51
+ *
52
+ * @param initialValue - 初始值
53
+ * @returns [state, setState, ref] - state 用于渲染,setState 同步更新 ref,ref 用于回调
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * const [content, setContent, contentRef] = useRefState('');
58
+ *
59
+ * const handler = {
60
+ * getContent: () => contentRef.current, // 始终是最新值
61
+ * setContent: (val) => {
62
+ * setContent(val); // 立即更新 ref
63
+ * // 此时 contentRef.current 已经是新值了
64
+ * }
65
+ * };
66
+ * ```
67
+ */ export function useRefState(initialValue) {
68
+ var _useState = _sliced_to_array(useState(initialValue), 2), state = _useState[0], setState = _useState[1];
69
+ var ref = useRef(initialValue);
70
+ // 每次渲染也同步(处理外部直接读取 state 后变化的情况)
71
+ ref.current = state;
72
+ var setRefState = useCallback(function(value) {
73
+ var newValue = typeof value === 'function' ? value(ref.current) : value;
74
+ ref.current = newValue; // 立即更新 ref
75
+ setState(newValue); // 触发重渲染
76
+ }, []);
77
+ return [
78
+ state,
79
+ setRefState,
80
+ ref
81
+ ];
82
+ }
83
+ export default useRefState;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Schema Editor Bridge Hook 返回值
3
+ */
4
+ export interface UseSchemaEditorBridgeResult {
5
+ /** 当前内容(内部状态) */
6
+ content: string;
7
+ /** 手动设置内容 */
8
+ setContent: (content: string) => void;
9
+ }
10
+ /**
11
+ * Bubble 专用的 Schema Editor Bridge Hook
12
+ * @description 使用单例模式管理全局监听器,避免多个 Bubble 组件冲突
13
+ * 开发环境自动启用,生产环境自动禁用
14
+ *
15
+ * @param id - Bubble 的唯一标识(data-id)
16
+ * @param initialContent - 初始内容
17
+ * @returns Hook 返回值,包含内容状态和控制方法
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const { content, setContent } = useSchemaEditorBridge(
22
+ * originData.id,
23
+ * originData.originContent || '',
24
+ * );
25
+ * ```
26
+ */
27
+ export declare function useSchemaEditorBridge(id: string | undefined, initialContent: string): UseSchemaEditorBridgeResult;
28
+ export default useSchemaEditorBridge;
@@ -0,0 +1,109 @@
1
+ function _array_like_to_array(arr, len) {
2
+ if (len == null || len > arr.length) len = arr.length;
3
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
+ return arr2;
5
+ }
6
+ function _array_with_holes(arr) {
7
+ if (Array.isArray(arr)) return arr;
8
+ }
9
+ function _iterable_to_array_limit(arr, i) {
10
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
11
+ if (_i == null) return;
12
+ var _arr = [];
13
+ var _n = true;
14
+ var _d = false;
15
+ var _s, _e;
16
+ try {
17
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
18
+ _arr.push(_s.value);
19
+ if (i && _arr.length === i) break;
20
+ }
21
+ } catch (err) {
22
+ _d = true;
23
+ _e = err;
24
+ } finally{
25
+ try {
26
+ if (!_n && _i["return"] != null) _i["return"]();
27
+ } finally{
28
+ if (_d) throw _e;
29
+ }
30
+ }
31
+ return _arr;
32
+ }
33
+ function _non_iterable_rest() {
34
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
35
+ }
36
+ function _sliced_to_array(arr, i) {
37
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
38
+ }
39
+ function _unsupported_iterable_to_array(o, minLen) {
40
+ if (!o) return;
41
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
42
+ var n = Object.prototype.toString.call(o).slice(8, -1);
43
+ if (n === "Object" && o.constructor) n = o.constructor.name;
44
+ if (n === "Map" || n === "Set") return Array.from(n);
45
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
46
+ }
47
+ import { useEffect } from "react";
48
+ import { SchemaEditorBridgeManager } from "./SchemaEditorBridgeManager";
49
+ import { useRefState } from "./useRefState";
50
+ /**
51
+ * Bubble 专用的 Schema Editor Bridge Hook
52
+ * @description 使用单例模式管理全局监听器,避免多个 Bubble 组件冲突
53
+ * 开发环境自动启用,生产环境自动禁用
54
+ *
55
+ * @param id - Bubble 的唯一标识(data-id)
56
+ * @param initialContent - 初始内容
57
+ * @returns Hook 返回值,包含内容状态和控制方法
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const { content, setContent } = useSchemaEditorBridge(
62
+ * originData.id,
63
+ * originData.originContent || '',
64
+ * );
65
+ * ```
66
+ */ export function useSchemaEditorBridge(id, initialContent) {
67
+ /** 开发环境自动启用 */ var enabled = process.env.NODE_ENV === 'development';
68
+ /**
69
+ * 内部状态:使用 useRefState 同时维护 state 和 ref
70
+ * @description setContent 会立即更新 ref,解决 set 后立即读取的问题
71
+ */ var _useRefState = _sliced_to_array(useRefState(initialContent), 3), content = _useRefState[0], setContent = _useRefState[1], contentRef = _useRefState[2];
72
+ /**
73
+ * 同步初始内容变化
74
+ * @description 当外部传入的 initialContent 变化时,更新内部状态
75
+ */ useEffect(function() {
76
+ setContent(initialContent);
77
+ }, [
78
+ initialContent
79
+ ]);
80
+ /**
81
+ * 注册到单例管理器
82
+ */ useEffect(function() {
83
+ var manager = SchemaEditorBridgeManager.getInstance();
84
+ /** 无 id 时直接返回 */ if (!id) return;
85
+ /** 禁用时注销已注册的 handler 并返回 */ if (!enabled) {
86
+ if (manager.has(id)) manager.unregister(id);
87
+ return;
88
+ }
89
+ /** 设置管理器启用状态 */ manager.setEnabled(true);
90
+ /** 创建处理器 */ var handler = {
91
+ getContent: function() {
92
+ return contentRef.current;
93
+ },
94
+ setContent: setContent
95
+ };
96
+ /** 注册 */ manager.register(id, handler);
97
+ /** 清理:组件卸载时注销 */ return function() {
98
+ manager.unregister(id);
99
+ };
100
+ }, [
101
+ id,
102
+ enabled
103
+ ]);
104
+ return {
105
+ content: content,
106
+ setContent: setContent
107
+ };
108
+ }
109
+ export default useSchemaEditorBridge;
@@ -251,6 +251,7 @@ import { BlockOutlined, DeleteFilled, ExclamationCircleOutlined, LoadingOutlined
251
251
  import { Image, Modal, Popover, Skeleton, Space } from "antd";
252
252
  import React, { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
253
253
  import { useDebounceFn } from "@ant-design/pro-components";
254
+ import { SquareArrowUpRight } from "@sofa-design/icons";
254
255
  import { Rnd } from "react-rnd";
255
256
  import { Path, Transforms } from "slate";
256
257
  import { ActionIconBox } from "../../../../Components/ActionIconBox";
@@ -279,9 +280,7 @@ import { getMediaType } from "../../utils/dom";
279
280
  console.log(editorProps);
280
281
  // 图片加载失败时显示为链接
281
282
  if (error) {
282
- return /*#__PURE__*/ React.createElement("a", {
283
- target: "_blank",
284
- rel: "noopener noreferrer",
283
+ return /*#__PURE__*/ React.createElement("span", {
285
284
  onClick: function(e) {
286
285
  var _editorProps_linkConfig, _editorProps_linkConfig1;
287
286
  e.stopPropagation();
@@ -310,7 +309,7 @@ import { getMediaType } from "../../utils/dom";
310
309
  style: {
311
310
  color: '#faad14'
312
311
  }
313
- }), props.alt || props.src || '图片链接');
312
+ }), props.alt || props.src || '图片链接', /*#__PURE__*/ React.createElement(SquareArrowUpRight, null));
314
313
  }
315
314
  if (editorProps === null || editorProps === void 0 ? void 0 : (_editorProps_image = editorProps.image) === null || _editorProps_image === void 0 ? void 0 : _editorProps_image.render) {
316
315
  var _editorProps_image_render, _editorProps_image1;
@@ -367,9 +366,7 @@ import { getMediaType } from "../../utils/dom";
367
366
  }, 160);
368
367
  // 如果图片加载失败,显示为链接
369
368
  if (error) {
370
- return /*#__PURE__*/ React.createElement("a", {
371
- target: "_blank",
372
- rel: "noopener noreferrer",
369
+ return /*#__PURE__*/ React.createElement("span", {
373
370
  onClick: function(e) {
374
371
  var _editorProps_linkConfig, _editorProps_linkConfig1;
375
372
  e.stopPropagation();
@@ -400,7 +397,7 @@ import { getMediaType } from "../../utils/dom";
400
397
  style: {
401
398
  color: '#faad14'
402
399
  }
403
- }), props.alt || props.src);
400
+ }), props.alt || props.src, /*#__PURE__*/ React.createElement(SquareArrowUpRight, null));
404
401
  }
405
402
  return /*#__PURE__*/ React.createElement("div", {
406
403
  "data-testid": "resize-image-container",
@@ -503,7 +500,7 @@ export function EditorImage(param) {
503
500
  var _state;
504
501
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
505
502
  var _useSelStatus = _sliced_to_array(useSelStatus(element), 2), _ = _useSelStatus[0], path = _useSelStatus[1];
506
- var _useEditorStore = useEditorStore(), markdownEditorRef = _useEditorStore.markdownEditorRef, readonly = _useEditorStore.readonly;
503
+ var _useEditorStore = useEditorStore(), markdownEditorRef = _useEditorStore.markdownEditorRef, readonly = _useEditorStore.readonly, editorProps = _useEditorStore.editorProps;
507
504
  var htmlRef = React.useRef(null);
508
505
  var _useState = _sliced_to_array(useState(false), 2), showAsText = _useState[0], setShowAsText = _useState[1];
509
506
  var _useGetSetState = _sliced_to_array(useGetSetState({
@@ -612,11 +609,8 @@ export function EditorImage(param) {
612
609
  }
613
610
  // 如果图片加载失败,显示为链接
614
611
  if (!state().loadSuccess) {
615
- var _state2, _state3;
616
- return /*#__PURE__*/ React.createElement("a", {
617
- href: ((_state2 = state()) === null || _state2 === void 0 ? void 0 : _state2.url) || (element === null || element === void 0 ? void 0 : element.url),
618
- target: "_blank",
619
- rel: "noopener noreferrer",
612
+ var _state2;
613
+ return /*#__PURE__*/ React.createElement("span", {
620
614
  style: {
621
615
  color: '#1890ff',
622
616
  textDecoration: 'underline',
@@ -631,12 +625,25 @@ export function EditorImage(param) {
631
625
  backgroundColor: '#fafafa',
632
626
  fontSize: '13px',
633
627
  lineHeight: '1.5'
628
+ },
629
+ onClick: function(e) {
630
+ var _state, _editorProps_linkConfig, _state1, _editorProps_linkConfig1;
631
+ if (!(((_state = state()) === null || _state === void 0 ? void 0 : _state.url) || (element === null || element === void 0 ? void 0 : element.url))) return;
632
+ e.stopPropagation();
633
+ e.preventDefault();
634
+ if ((_editorProps_linkConfig = editorProps.linkConfig) === null || _editorProps_linkConfig === void 0 ? void 0 : _editorProps_linkConfig.onClick) {
635
+ var _state2;
636
+ if (editorProps.linkConfig.onClick(((_state2 = state()) === null || _state2 === void 0 ? void 0 : _state2.url) || (element === null || element === void 0 ? void 0 : element.url) || '') === false) {
637
+ return;
638
+ }
639
+ }
640
+ window.open(((_state1 = state()) === null || _state1 === void 0 ? void 0 : _state1.url) || (element === null || element === void 0 ? void 0 : element.url), (editorProps === null || editorProps === void 0 ? void 0 : (_editorProps_linkConfig1 = editorProps.linkConfig) === null || _editorProps_linkConfig1 === void 0 ? void 0 : _editorProps_linkConfig1.openInNewTab) ? '_blank' : '_self');
634
641
  }
635
642
  }, /*#__PURE__*/ React.createElement(ExclamationCircleOutlined, {
636
643
  style: {
637
644
  color: '#faad14'
638
645
  }
639
- }), (element === null || element === void 0 ? void 0 : element.alt) || ((_state3 = state()) === null || _state3 === void 0 ? void 0 : _state3.url) || (element === null || element === void 0 ? void 0 : element.url) || '图片链接');
646
+ }), (element === null || element === void 0 ? void 0 : element.alt) || ((_state2 = state()) === null || _state2 === void 0 ? void 0 : _state2.url) || (element === null || element === void 0 ? void 0 : element.url) || '图片链接', /*#__PURE__*/ React.createElement(SquareArrowUpRight, null));
640
647
  }
641
648
  return !readonly ? /*#__PURE__*/ React.createElement(ResizeImage, {
642
649
  defaultSize: {
@@ -227,6 +227,7 @@ import { DeleteFilled, ExclamationCircleOutlined, EyeOutlined, LoadingOutlined }
227
227
  import { Modal, Popover, Skeleton } from "antd";
228
228
  import React, { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
229
229
  import { useDebounceFn } from "@ant-design/pro-components";
230
+ import { SquareArrowUpRight } from "@sofa-design/icons";
230
231
  import { Rnd } from "react-rnd";
231
232
  import { Transforms } from "slate";
232
233
  import { ActionIconBox } from "../../../Components/ActionIconBox";
@@ -597,9 +598,7 @@ export function Media(param) {
597
598
  }
598
599
  if (!state().loadSuccess) {
599
600
  var _state1;
600
- return /*#__PURE__*/ React.createElement("a", {
601
- target: "_blank",
602
- rel: "noopener noreferrer",
601
+ return /*#__PURE__*/ React.createElement("span", {
603
602
  onClick: function(e) {
604
603
  var _state, _editorProps_linkConfig, _state1, _editorProps_linkConfig1;
605
604
  if (!((_state = state()) === null || _state === void 0 ? void 0 : _state.url)) return;
@@ -630,7 +629,7 @@ export function Media(param) {
630
629
  style: {
631
630
  color: '#faad14'
632
631
  }
633
- }), element.alt || ((_state1 = state()) === null || _state1 === void 0 ? void 0 : _state1.url) || (element === null || element === void 0 ? void 0 : element.url) || '视频链接');
632
+ }), element.alt || ((_state1 = state()) === null || _state1 === void 0 ? void 0 : _state1.url) || (element === null || element === void 0 ? void 0 : element.url) || '视频链接', /*#__PURE__*/ React.createElement(SquareArrowUpRight, null));
634
633
  }
635
634
  return /*#__PURE__*/ React.createElement("video", {
636
635
  "data-testid": "video-element",
@@ -703,9 +702,7 @@ export function Media(param) {
703
702
  }
704
703
  if (!state().loadSuccess) {
705
704
  var _state3;
706
- return /*#__PURE__*/ React.createElement("a", {
707
- target: "_blank",
708
- rel: "noopener noreferrer",
705
+ return /*#__PURE__*/ React.createElement("span", {
709
706
  onClick: function(e) {
710
707
  var _state, _editorProps_linkConfig, _state1, _editorProps_linkConfig1;
711
708
  if (!(((_state = state()) === null || _state === void 0 ? void 0 : _state.url) || (element === null || element === void 0 ? void 0 : element.url))) return;
@@ -736,7 +733,7 @@ export function Media(param) {
736
733
  style: {
737
734
  color: '#faad14'
738
735
  }
739
- }), element.alt || ((_state3 = state()) === null || _state3 === void 0 ? void 0 : _state3.url) || (element === null || element === void 0 ? void 0 : element.url) || '音频链接');
736
+ }), element.alt || ((_state3 = state()) === null || _state3 === void 0 ? void 0 : _state3.url) || (element === null || element === void 0 ? void 0 : element.url) || '音频链接', /*#__PURE__*/ React.createElement(SquareArrowUpRight, null));
740
737
  }
741
738
  return /*#__PURE__*/ React.createElement("audio", {
742
739
  "data-testid": "audio-element",
@@ -83,15 +83,14 @@ var genStyle = function(token) {
83
83
  '&-edit-area': {
84
84
  outline: 'none !important'
85
85
  },
86
- '&-container': {
87
- },
88
- '&-content': _define_property({
86
+ '&-container': _define_property({
89
87
  // 默认 padding,可以通过 contentStyle 覆盖
90
88
  // 使用 CSS 变量,允许通过内联样式覆盖
91
89
  padding: 'var(--content-padding, 4px 20px)'
92
90
  }, "@media (max-width: ".concat(MOBILE_BREAKPOINT, ")"), {
93
91
  padding: 'var(--content-padding, 4px 4px)'
94
- })
92
+ }),
93
+ '&-content': {}
95
94
  });
96
95
  };
97
96
  /**
package/dist/index.d.ts CHANGED
@@ -85,3 +85,9 @@ export * from './Components/TypingAnimation';
85
85
  export * from './MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem';
86
86
  export * from './MarkdownInputField/AttachmentButton/AttachmentFileList';
87
87
  export * from './MarkdownInputField/AttachmentButton/utils';
88
+ /**
89
+ * Schema Editor Chrome 插件底层 SDK
90
+ * @description 原始 SDK 导出,一般用户无需直接使用
91
+ * 推荐通过 Bubble 组件的 schemaEditorConfig 属性集成
92
+ */
93
+ export * from '@schema-editor/host-sdk';
package/dist/index.js CHANGED
@@ -102,3 +102,8 @@ export * from "./Components/TypingAnimation";
102
102
  export * from "./MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem";
103
103
  export * from "./MarkdownInputField/AttachmentButton/AttachmentFileList";
104
104
  export * from "./MarkdownInputField/AttachmentButton/utils";
105
+ /**
106
+ * Schema Editor Chrome 插件底层 SDK
107
+ * @description 原始 SDK 导出,一般用户无需直接使用
108
+ * 推荐通过 Bubble 组件的 schemaEditorConfig 属性集成
109
+ */ export * from "@schema-editor/host-sdk";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ant-design/agentic-ui",
3
- "version": "2.27.1",
3
+ "version": "2.27.3",
4
4
  "description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
5
5
  "repository": "git@github.com:ant-design/agentic-ui.git",
6
6
  "license": "MIT",
@@ -53,6 +53,7 @@
53
53
  "@better-scroll/scroll-bar": "^2.5.1",
54
54
  "@galacean/effects": "^2.6.5",
55
55
  "@juggle/resize-observer": "^3.4.0",
56
+ "@schema-editor/host-sdk": "^1.2.0",
56
57
  "@sofa-design/icons": "^1.6.1",
57
58
  "ace-builds": "^1.43.4",
58
59
  "ajv": "^8.17.1",