@ant-design/agentic-ui 2.30.30 → 2.30.31

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.
Files changed (50) hide show
  1. package/dist/Bubble/AIBubble.js +6 -3
  2. package/dist/Bubble/List/PureBubbleList.js +22 -1
  3. package/dist/Bubble/List/index.js +7 -5
  4. package/dist/Bubble/MessagesContent/BubbleExtra.js +4 -2
  5. package/dist/Components/ActionIconBox/index.js +8 -8
  6. package/dist/Hooks/useLanguage.d.ts +1 -0
  7. package/dist/I18n/locales.d.ts +1 -0
  8. package/dist/I18n/locales.js +2 -0
  9. package/dist/MarkdownEditor/editor/parser/parse/parseHtml.js +15 -6
  10. package/dist/MarkdownEditor/style.js +0 -4
  11. package/dist/MarkdownInputField/SendButton/index.d.ts +2 -2
  12. package/dist/MarkdownInputField/SendButton/index.js +44 -26
  13. package/dist/MarkdownInputField/SendButton/sendButtonPalette.d.ts +36 -0
  14. package/dist/MarkdownInputField/SendButton/sendButtonPalette.js +247 -0
  15. package/dist/MarkdownInputField/SendButton/style.js +3 -3
  16. package/dist/MarkdownInputField/style.js +3 -1
  17. package/dist/MarkdownRenderer/AnimationText.js +1 -2
  18. package/dist/MarkdownRenderer/CharacterQueue.js +3 -0
  19. package/dist/MarkdownRenderer/MarkdownRenderer.js +5 -18
  20. package/dist/MarkdownRenderer/markdownReactShared.d.ts +2 -1
  21. package/dist/MarkdownRenderer/markdownReactShared.js +57 -19
  22. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +14 -10
  23. package/dist/MarkdownRenderer/streaming/fenceTracker.d.ts +7 -0
  24. package/dist/MarkdownRenderer/streaming/fenceTracker.js +28 -0
  25. package/dist/MarkdownRenderer/streaming/lastBlockThrottle.js +3 -1
  26. package/dist/MarkdownRenderer/streaming/useShallowMemo.d.ts +1 -0
  27. package/dist/MarkdownRenderer/streaming/useShallowMemo.js +36 -0
  28. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +6 -3
  29. package/dist/MarkdownRenderer/useStreaming.js +43 -41
  30. package/dist/Plugins/chart/components/ChartContainer/ChartErrorBoundary.d.ts +2 -0
  31. package/dist/TaskList/TaskList.js +25 -13
  32. package/dist/TaskList/constants.d.ts +1 -1
  33. package/dist/TaskList/constants.js +9 -4
  34. package/dist/TaskList/style.js +29 -11
  35. package/dist/ToolUseBarThink/index.d.ts +0 -23
  36. package/dist/ToolUseBarThink/index.js +178 -315
  37. package/dist/ToolUseBarThink/style.js +64 -48
  38. package/dist/Types/quicklink.d.ts +1 -1
  39. package/dist/Workspace/File/FileTree/FileTreeComponent.d.ts +4 -0
  40. package/dist/Workspace/File/FileTree/FileTreeComponent.js +283 -0
  41. package/dist/Workspace/File/FileTree/index.d.ts +2 -0
  42. package/dist/Workspace/File/FileTree/index.js +1 -0
  43. package/dist/Workspace/File/FileTree/style.d.ts +8 -0
  44. package/dist/Workspace/File/FileTree/style.js +80 -0
  45. package/dist/Workspace/File/index.d.ts +2 -1
  46. package/dist/Workspace/File/index.js +1 -0
  47. package/dist/Workspace/index.d.ts +4 -2
  48. package/dist/Workspace/index.js +73 -36
  49. package/dist/Workspace/types.d.ts +70 -2
  50. package/package.json +2 -1
@@ -272,14 +272,14 @@ var getTaskList = function getTaskList(originData) {
272
272
  * </AIBubble>
273
273
  * ```
274
274
  */ export var AIBubble = /*#__PURE__*/ memo(function(props) {
275
- var _ref, _messageDisplayKeyRef_current, _props_readonly;
275
+ var _messageDisplayKeyRef_current, _props_readonly;
276
276
  var _props_originData, _props_originData1, _props_originData2, _props_originData3, _props_originData4, _props_originData5, _props_bubbleRenderConfig, _props_originData_fileMap, _props_originData6, _props_markdownRenderConfig, _props_bubbleRenderConfig1, _props_styles, _props_bubbleRenderConfig2, _bubbleRenderConfig_render;
277
277
  var onAvatarClick = props.onAvatarClick, className = props.className, style = props.style, bubbleRenderConfig = props.bubbleRenderConfig, classNames = props.classNames, styles = props.styles, originData = props.originData, preMessage = props.preMessage;
278
278
  var _React_useState = _sliced_to_array(React.useState(false), 2), hidePadding = _React_useState[0], setHidePadding = _React_useState[1];
279
279
  var messageDisplayKeyRef = useRef(null);
280
280
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
281
281
  var context = useContext(BubbleConfigContext);
282
- var _ref1 = context || {}, compact = _ref1.compact, standalone = _ref1.standalone, extraShowOnHover = _ref1.extraShowOnHover;
282
+ var _ref = context || {}, compact = _ref.compact, standalone = _ref.standalone, extraShowOnHover = _ref.extraShowOnHover;
283
283
  var prefixClass = getPrefixCls('agentic');
284
284
  var _useStyle = useStyle(prefixClass), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
285
285
  var preMessageSameRole = isSameRoleAsPrevious(preMessage, originData);
@@ -310,7 +310,10 @@ var getTaskList = function getTaskList(originData) {
310
310
  messageDisplayKeyRef.current = nanoid();
311
311
  }
312
312
  }
313
- var messageDisplayKey = (_ref = (_messageDisplayKeyRef_current = messageDisplayKeyRef.current) !== null && _messageDisplayKeyRef_current !== void 0 ? _messageDisplayKeyRef_current : id) !== null && _ref !== void 0 ? _ref : nanoid();
313
+ if (!messageDisplayKeyRef.current && !id) {
314
+ messageDisplayKeyRef.current = nanoid();
315
+ }
316
+ var messageDisplayKey = (_messageDisplayKeyRef_current = messageDisplayKeyRef.current) !== null && _messageDisplayKeyRef_current !== void 0 ? _messageDisplayKeyRef_current : id;
314
317
  var rawContent = props === null || props === void 0 ? void 0 : (_props_originData1 = props.originData) === null || _props_originData1 === void 0 ? void 0 : _props_originData1.content;
315
318
  var _useMemo = useMemo(function() {
316
319
  return extractFilemapBlocks(typeof rawContent === 'string' ? rawContent : '');
@@ -177,7 +177,28 @@ export var PureBubbleList = /*#__PURE__*/ React.memo(function(props) {
177
177
  }, [
178
178
  bubbleList,
179
179
  props.style,
180
- props.lazy
180
+ props.lazy,
181
+ bubbleListRef,
182
+ bubbleRenderConfig,
183
+ classNames,
184
+ props.bubbleRef,
185
+ markdownRenderConfig,
186
+ docListProps,
187
+ styles,
188
+ props.readonly,
189
+ onReply,
190
+ onDislike,
191
+ onDisLike,
192
+ onLike,
193
+ onLikeCancel,
194
+ onCancelLike,
195
+ onAvatarClick,
196
+ onDoubleClick,
197
+ shouldShowCopy,
198
+ shouldShowVoice,
199
+ userMeta,
200
+ assistantMeta,
201
+ deps
181
202
  ]);
182
203
  if (isLoading) {
183
204
  return wrapSSR(/*#__PURE__*/ React.createElement("div", {
@@ -154,12 +154,16 @@ import { useStyle } from "./style";
154
154
  ]);
155
155
  var prefixClass = getPrefixCls('agentic-bubble-list');
156
156
  var _useStyle = useStyle(prefixClass), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
157
+ var prevStyleRef = useRef(props.style);
158
+ if (props.style !== prevStyleRef.current && !shallowEqualRecord(props.style || {}, prevStyleRef.current || {})) {
159
+ prevStyleRef.current = props.style;
160
+ }
157
161
  var deps = useMemo(function() {
158
162
  return [
159
- props.style
163
+ prevStyleRef.current
160
164
  ];
161
165
  }, [
162
- JSON.stringify(props.style)
166
+ prevStyleRef.current
163
167
  ]);
164
168
  // 为 loading 项生成唯一的 key,使用 ref 缓存以确保稳定性
165
169
  var loadingKeysRef = useRef(new Map());
@@ -224,11 +228,9 @@ import { useStyle } from "./style";
224
228
  var useLazyWrapper = !!isLazyEnabled && ((_ref = (_props_lazy = props.lazy) === null || _props_lazy === void 0 ? void 0 : (_props_lazy_shouldLazyLoad = _props_lazy.shouldLazyLoad) === null || _props_lazy_shouldLazyLoad === void 0 ? void 0 : _props_lazy_shouldLazyLoad.call(_props_lazy, index, totalCount)) !== null && _ref !== void 0 ? _ref : true);
225
229
  var bubbleElement = /*#__PURE__*/ React.createElement("div", {
226
230
  key: itemKey,
227
- style: useLazyWrapper ? {
231
+ style: {
228
232
  minWidth: 0,
229
233
  width: '100%'
230
- } : {
231
- display: 'contents'
232
234
  },
233
235
  "data-bubble-list-item": true,
234
236
  "data-is-last": isLast ? 'true' : 'false'
@@ -448,7 +448,8 @@ import { VoiceButton } from "./VoiceButton";
448
448
  originalData === null || originalData === void 0 ? void 0 : originalData.isFinished,
449
449
  typing,
450
450
  feedbackLoading,
451
- props.onLikeCancel || props.onCancelLike
451
+ props.onLikeCancel,
452
+ props.onCancelLike
452
453
  ]);
453
454
  var disLike = useMemo(function() {
454
455
  return shouldShowDisLike && !typing ? /*#__PURE__*/ React.createElement(ActionIconBox, {
@@ -698,7 +699,8 @@ import { VoiceButton } from "./VoiceButton";
698
699
  var _props_onRenderExtraNull;
699
700
  (_props_onRenderExtraNull = props.onRenderExtraNull) === null || _props_onRenderExtraNull === void 0 ? void 0 : _props_onRenderExtraNull.call(props, !dom && !reSend);
700
701
  }, [
701
- dom
702
+ dom,
703
+ reSend
702
704
  ]);
703
705
  // 检查是否有任何内容需要渲染
704
706
  var hasLeftContent = typing && originalData.content !== '...' || reSend;
@@ -356,11 +356,11 @@ import { useStyle } from "./style";
356
356
  return _ts_generator(this, function(_state) {
357
357
  switch(_state.label){
358
358
  case 0:
359
- e.preventDefault();
360
- e.stopPropagation();
361
359
  if (!props.onClick) return [
362
360
  2
363
361
  ];
362
+ e.preventDefault();
363
+ e.stopPropagation();
364
364
  if (loading) return [
365
365
  2
366
366
  ];
@@ -413,11 +413,11 @@ import { useStyle } from "./style";
413
413
  3,
414
414
  5
415
415
  ];
416
- e.preventDefault();
417
- e.stopPropagation();
418
416
  if (!props.onClick) return [
419
417
  2
420
418
  ];
419
+ e.preventDefault();
420
+ e.stopPropagation();
421
421
  if (loading) return [
422
422
  2
423
423
  ];
@@ -482,11 +482,11 @@ import { useStyle } from "./style";
482
482
  return _ts_generator(this, function(_state) {
483
483
  switch(_state.label){
484
484
  case 0:
485
- e.preventDefault();
486
- e.stopPropagation();
487
485
  if (!props.onClick) return [
488
486
  2
489
487
  ];
488
+ e.preventDefault();
489
+ e.stopPropagation();
490
490
  if (loading) return [
491
491
  2
492
492
  ];
@@ -539,11 +539,11 @@ import { useStyle } from "./style";
539
539
  3,
540
540
  5
541
541
  ];
542
- e.preventDefault();
543
- e.stopPropagation();
544
542
  if (!props.onClick) return [
545
543
  2
546
544
  ];
545
+ e.preventDefault();
546
+ e.stopPropagation();
547
547
  if (loading) return [
548
548
  2
549
549
  ];
@@ -289,6 +289,7 @@ export declare function useLanguage(): {
289
289
  'workspace.browser': string;
290
290
  'workspace.task': string;
291
291
  'workspace.file': string;
292
+ 'workspace.fileTree': string;
292
293
  'workspace.custom': string;
293
294
  'workspace.terminalExecution': string;
294
295
  'workspace.createHtmlFile': string;
@@ -251,6 +251,7 @@ export declare const cnLabels: {
251
251
  'workspace.browser': string;
252
252
  'workspace.task': string;
253
253
  'workspace.file': string;
254
+ 'workspace.fileTree': string;
254
255
  'workspace.custom': string;
255
256
  'workspace.terminalExecution': string;
256
257
  'workspace.createHtmlFile': string;
@@ -262,6 +262,7 @@
262
262
  'workspace.browser': '浏览器',
263
263
  'workspace.task': '任务',
264
264
  'workspace.file': '文件',
265
+ 'workspace.fileTree': '文件树',
265
266
  'workspace.custom': '自定义',
266
267
  'workspace.terminalExecution': '终端执行',
267
268
  'workspace.createHtmlFile': '创建 HTML 文件',
@@ -722,6 +723,7 @@
722
723
  'workspace.browser': 'Browser',
723
724
  'workspace.task': 'Task',
724
725
  'workspace.file': 'File',
726
+ 'workspace.fileTree': 'File tree',
725
727
  'workspace.custom': 'Custom',
726
728
  'workspace.terminalExecution': 'Terminal execution',
727
729
  'workspace.createHtmlFile': 'Create HTML file',
@@ -123,22 +123,31 @@ import partialJsonParse from "../json-parse";
123
123
  var THINK_TAG_CANONICAL_CLOSE = '</think>';
124
124
  /** 部分模型输出的外壳别名;拼接避免与规范标签在源码中混淆 */ var REDACTED_THINKING_ALIAS_OPEN = '<' + 'redacted_' + 'thinking' + '>';
125
125
  var REDACTED_THINKING_ALIAS_CLOSE = '</' + 'redacted_' + 'thinking' + '>';
126
+ var THINKING_ALIAS_OPEN = '<' + 'thinking' + '>';
127
+ var THINKING_ALIAS_CLOSE = '</' + 'thinking' + '>';
126
128
  var escapeRegExp = function escapeRegExp(value) {
127
129
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
128
130
  };
129
131
  /** 仅替换「成对」别名标签,避免正文里偶然出现的孤立字面量被误换 */ var REDACTED_THINKING_ALIAS_PAIR_REGEX = new RegExp("".concat(escapeRegExp(REDACTED_THINKING_ALIAS_OPEN), "([\\s\\S]*?)").concat(escapeRegExp(REDACTED_THINKING_ALIAS_CLOSE)), 'gi');
132
+ var THINKING_ALIAS_PAIR_REGEX = new RegExp("".concat(escapeRegExp(THINKING_ALIAS_OPEN), "([\\s\\S]*?)").concat(escapeRegExp(THINKING_ALIAS_CLOSE)), 'gi');
130
133
  var FIND_THINK_CANONICAL_BLOCK_RE = new RegExp("^\\s*".concat(escapeRegExp(THINK_TAG_CANONICAL_OPEN), "([\\s\\S]*?)").concat(escapeRegExp(THINK_TAG_CANONICAL_CLOSE), "\\s*$"), 'i');
131
- var FIND_THINK_ALIAS_BLOCK_RE = new RegExp("^\\s*".concat(escapeRegExp(REDACTED_THINKING_ALIAS_OPEN), "([\\s\\S]*?)").concat(escapeRegExp(REDACTED_THINKING_ALIAS_CLOSE), "\\s*$"), 'i');
134
+ var FIND_THINK_ALIAS_BLOCK_RE = new RegExp("^\\s*(?:".concat(escapeRegExp(REDACTED_THINKING_ALIAS_OPEN), "|").concat(escapeRegExp(THINKING_ALIAS_OPEN), ")([\\s\\S]*?)(?:").concat(escapeRegExp(REDACTED_THINKING_ALIAS_CLOSE), "|").concat(escapeRegExp(THINKING_ALIAS_CLOSE), ")\\s*$"), 'i');
132
135
  /**
133
136
  * 将成对的别名标签 `<think>`…`</think>` 归一为与 `preprocessSpecialTags(..., 'think')` 契约一致的规范标签。
134
137
  * 否则 `preprocessThinkTags` 无法把思考区内的 ``` 围栏换成 【CODE_BLOCK】,内层 JSON 会变成顶层独立 code 节点。
135
138
  */ export function normalizeThinkTagAliases(markdown) {
136
- if (!markdown || markdown.indexOf(REDACTED_THINKING_ALIAS_OPEN) === -1) {
137
- return markdown;
138
- }
139
- return markdown.replace(REDACTED_THINKING_ALIAS_PAIR_REGEX, function(_match, inner) {
139
+ if (!markdown) return markdown;
140
+ var replaceToCanonical = function replaceToCanonical(_match, inner) {
140
141
  return "".concat(THINK_TAG_CANONICAL_OPEN).concat(inner).concat(THINK_TAG_CANONICAL_CLOSE);
141
- });
142
+ };
143
+ var result = markdown;
144
+ if (result.indexOf(REDACTED_THINKING_ALIAS_OPEN) !== -1) {
145
+ result = result.replace(REDACTED_THINKING_ALIAS_PAIR_REGEX, replaceToCanonical);
146
+ }
147
+ if (result.indexOf(THINKING_ALIAS_OPEN) !== -1) {
148
+ result = result.replace(THINKING_ALIAS_PAIR_REGEX, replaceToCanonical);
149
+ }
150
+ return result;
142
151
  }
143
152
  /**
144
153
  * 解码 URI 组件,处理错误情况
@@ -367,10 +367,6 @@ var genStyle = function genStyle(token) {
367
367
  }, "@media (max-width: ".concat(MOBILE_BREAKPOINT, ")"), {
368
368
  padding: 'var(--agentic-ui-content-padding, 4px 4px)'
369
369
  }),
370
- '&-content': {
371
- '--margin-4x': 'var(--agentic-ui-editor-margin-4x, 6px)',
372
- '--margin-2x': 'var(--agentic-ui-editor-margin-2x, 4px)'
373
- },
374
370
  '&-focus': {
375
371
  height: 64
376
372
  }
@@ -83,7 +83,7 @@ type SendButtonProps = {
83
83
  * @component
84
84
  * @description 发送按钮组件,支持多种状态和动画效果
85
85
  * @param {SendButtonProps} props - 组件属性
86
- * @param {boolean} props.isHover - 指示鼠标是否悬停在按钮上
86
+ * @param {boolean} props.isSendable - 是否处于可发送状态
87
87
  * @param {boolean} props.disabled - 指示按钮是否禁用
88
88
  * @param {boolean} props.typing - 指示是否处于输入状态
89
89
  * @param {() => void} props.onClick - 点击按钮时的回调函数
@@ -95,7 +95,7 @@ type SendButtonProps = {
95
95
  * @example
96
96
  * ```tsx
97
97
  * <SendButton
98
- * isHover={false}
98
+ * isSendable
99
99
  * disabled={false}
100
100
  * typing={false}
101
101
  * onClick={() => console.log('发送消息')}
@@ -86,13 +86,14 @@ function _object_without_properties_loose(source, excluded) {
86
86
  }
87
87
  return target;
88
88
  }
89
- import { ConfigProvider, Tooltip } from "antd";
89
+ import { ConfigProvider, Tooltip, theme as antdTheme } from "antd";
90
90
  import classNames from "clsx";
91
91
  import { motion } from "framer-motion";
92
- import React, { useContext, useEffect } from "react";
92
+ import React, { useContext, useEffect, useMemo } from "react";
93
93
  import { ErrorBoundary } from "react-error-boundary";
94
94
  import { STOP_ICON_DISK_FILL, STOP_ICON_HALO_FILL, StopIcon } from "../../AgentRunBar/icons";
95
95
  import { I18nContext } from "../../I18n";
96
+ import { getSendButtonPalette, resolveSendButtonDisplayColors } from "./sendButtonPalette";
96
97
  import { useStyle } from "./style";
97
98
  /**
98
99
  * 解析发送按钮的最终禁用状态:用户显式传入优先,否则按上传状态判断
@@ -100,18 +101,12 @@ import { useStyle } from "./style";
100
101
  var _ref;
101
102
  return (_ref = sendButtonProps === null || sendButtonProps === void 0 ? void 0 : sendButtonProps.disabled) !== null && _ref !== void 0 ? _ref : fileUploadStatus === 'uploading';
102
103
  }
103
- /** 未传入 `colors` 时使用 CSS 语义变量(与原先全局 SVG 覆盖一致) */ var SEND_BUTTON_THEME_COLORS = {
104
- icon: 'var(--color-gray-bg-card-white, #ffffff)',
105
- iconHover: 'var(--color-gray-bg-card-white, #ffffff)',
106
- background: 'var(--color-primary-control-fill-primary, #1677ff)',
107
- backgroundHover: 'var(--color-primary-control-fill-primary, #1677ff)'
108
- };
109
104
  function SendIcon(props) {
110
- var _ref, _ref1, _ref2, _ref3;
111
- var hover = props.hover, typing = props.typing, colors = props.colors, rest = _object_without_properties(props, [
112
- "hover",
105
+ var isActive = props.isActive, disabled = props.disabled, typing = props.typing, displayColors = props.displayColors, rest = _object_without_properties(props, [
106
+ "isActive",
107
+ "disabled",
113
108
  "typing",
114
- "colors"
109
+ "displayColors"
115
110
  ]);
116
111
  if (typing) {
117
112
  return /*#__PURE__*/ React.createElement(StopIcon, _object_spread_props(_object_spread({}, rest), {
@@ -119,12 +114,9 @@ function SendIcon(props) {
119
114
  haloFill: STOP_ICON_HALO_FILL
120
115
  }));
121
116
  }
122
- var currentColors = {
123
- icon: (_ref = colors === null || colors === void 0 ? void 0 : colors.icon) !== null && _ref !== void 0 ? _ref : SEND_BUTTON_THEME_COLORS.icon,
124
- iconHover: (_ref1 = colors === null || colors === void 0 ? void 0 : colors.iconHover) !== null && _ref1 !== void 0 ? _ref1 : SEND_BUTTON_THEME_COLORS.iconHover,
125
- background: (_ref2 = colors === null || colors === void 0 ? void 0 : colors.background) !== null && _ref2 !== void 0 ? _ref2 : SEND_BUTTON_THEME_COLORS.background,
126
- backgroundHover: (_ref3 = colors === null || colors === void 0 ? void 0 : colors.backgroundHover) !== null && _ref3 !== void 0 ? _ref3 : SEND_BUTTON_THEME_COLORS.backgroundHover
127
- };
117
+ var useActive = isActive && !disabled;
118
+ var circleFill = useActive ? displayColors.backgroundActive : displayColors.backgroundMuted;
119
+ var arrowFill = useActive ? displayColors.iconActive : displayColors.iconMuted;
128
120
  return /*#__PURE__*/ React.createElement("svg", _object_spread({
129
121
  xmlns: "http://www.w3.org/2000/svg",
130
122
  fill: "none",
@@ -137,8 +129,8 @@ function SendIcon(props) {
137
129
  r: "0.5em",
138
130
  initial: false,
139
131
  animate: {
140
- fill: hover ? currentColors.backgroundHover : currentColors.background,
141
- fillOpacity: hover ? 1 : 0.03530000150203705
132
+ fill: circleFill,
133
+ fillOpacity: 1
142
134
  },
143
135
  transition: {
144
136
  duration: 0.6,
@@ -149,8 +141,8 @@ function SendIcon(props) {
149
141
  fillRule: "evenodd",
150
142
  initial: false,
151
143
  animate: {
152
- fill: hover ? currentColors.iconHover : currentColors.icon,
153
- fillOpacity: hover ? 1 : 0.24709999561309814
144
+ fill: arrowFill,
145
+ fillOpacity: 1
154
146
  },
155
147
  transition: {
156
148
  duration: 0.2,
@@ -167,7 +159,7 @@ function SendIcon(props) {
167
159
  * @component
168
160
  * @description 发送按钮组件,支持多种状态和动画效果
169
161
  * @param {SendButtonProps} props - 组件属性
170
- * @param {boolean} props.isHover - 指示鼠标是否悬停在按钮上
162
+ * @param {boolean} props.isSendable - 是否处于可发送状态
171
163
  * @param {boolean} props.disabled - 指示按钮是否禁用
172
164
  * @param {boolean} props.typing - 指示是否处于输入状态
173
165
  * @param {() => void} props.onClick - 点击按钮时的回调函数
@@ -179,7 +171,7 @@ function SendIcon(props) {
179
171
  * @example
180
172
  * ```tsx
181
173
  * <SendButton
182
- * isHover={false}
174
+ * isSendable
183
175
  * disabled={false}
184
176
  * typing={false}
185
177
  * onClick={() => console.log('发送消息')}
@@ -210,10 +202,36 @@ function SendIcon(props) {
210
202
  // 仅在挂载时触发一次,避免引用变化导致重复打点
211
203
  // eslint-disable-next-line react-hooks/exhaustive-deps -- onInit intentionally once on mount
212
204
  }, []);
205
+ var token = antdTheme.useToken().token;
213
206
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
214
207
  var locale = useContext(I18nContext).locale;
215
208
  var baseCls = getPrefixCls('agentic-md-input-field-send-button');
216
209
  var _useStyle = useStyle(baseCls), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
210
+ var displayColors = useMemo(function() {
211
+ return resolveSendButtonDisplayColors(getSendButtonPalette({
212
+ colorPrimary: token.colorPrimary,
213
+ colorBgContainer: token.colorBgContainer,
214
+ colorTextLightSolid: token.colorTextLightSolid,
215
+ colorTextTertiary: token.colorTextTertiary,
216
+ colorFillTertiary: token.colorFillTertiary,
217
+ colorText: token.colorText
218
+ }), colors, {
219
+ colorPrimary: token.colorPrimary,
220
+ colorBgContainer: token.colorBgContainer,
221
+ colorTextLightSolid: token.colorTextLightSolid,
222
+ colorTextTertiary: token.colorTextTertiary,
223
+ colorFillTertiary: token.colorFillTertiary,
224
+ colorText: token.colorText
225
+ });
226
+ }, [
227
+ colors,
228
+ token.colorBgContainer,
229
+ token.colorFillTertiary,
230
+ token.colorPrimary,
231
+ token.colorText,
232
+ token.colorTextLightSolid,
233
+ token.colorTextTertiary
234
+ ]);
217
235
  if (typeof window === 'undefined' || typeof document === 'undefined' || !window.document) {
218
236
  // SSR 环境下不渲染
219
237
  return null;
@@ -257,9 +275,9 @@ function SendIcon(props) {
257
275
  }, /*#__PURE__*/ React.createElement(ErrorBoundary, {
258
276
  fallback: /*#__PURE__*/ React.createElement("div", null)
259
277
  }, /*#__PURE__*/ React.createElement(SendIcon, {
260
- hover: isSendable && !disabled,
278
+ isActive: isSendable,
261
279
  disabled: disabled,
262
280
  typing: typing,
263
- colors: colors
281
+ displayColors: displayColors
264
282
  })))));
265
283
  };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * 发送按钮默认色板:用 Ant Design token 的实色保证相对 colorBgContainer 的对比度,
3
+ * 随亮色 / 暗色主题切换。半透明 token 先与 colorBgContainer 叠算再比对比度、再混合。
4
+ */
5
+ export interface SendButtonPaletteToken {
6
+ colorPrimary: string;
7
+ colorBgContainer: string;
8
+ colorTextLightSolid: string;
9
+ colorTextTertiary: string;
10
+ colorFillTertiary: string;
11
+ colorText?: string;
12
+ }
13
+ /**
14
+ * 基于当前主题 token 生成默认可发送 / 未激活填充与图标色
15
+ */
16
+ export declare function getSendButtonPalette(token: SendButtonPaletteToken): {
17
+ readonly backgroundActive: string;
18
+ readonly backgroundMuted: string;
19
+ readonly iconActive: string;
20
+ readonly iconMuted: string;
21
+ };
22
+ export type SendButtonResolvedColors = {
23
+ backgroundActive: string;
24
+ backgroundMuted: string;
25
+ iconActive: string;
26
+ iconMuted: string;
27
+ };
28
+ /**
29
+ * 合并默认色板与用户 `colors`;与原先 background/backgroundHover、icon/iconHover 语义一致
30
+ */
31
+ export declare function resolveSendButtonDisplayColors(basePalette: SendButtonResolvedColors, colors: {
32
+ icon?: string;
33
+ iconHover?: string;
34
+ background?: string;
35
+ backgroundHover?: string;
36
+ } | undefined, token: SendButtonPaletteToken): SendButtonResolvedColors;