@ai-group/chat-sdk 3.7.1-alpha5 → 3.7.1-alpha8
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.
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.d.ts +11 -1
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +144 -14
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js +44 -0
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/index.d.ts +2 -2
- package/dist/cjs/components/XAdkChatbot/index.js +43 -13
- package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.d.ts +7 -2
- package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.js +68 -17
- package/dist/cjs/components/XAdkProvider/compound/DefaultLayout.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/compound/Sender.d.ts +2 -1
- package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/compound/styles.d.ts +1 -0
- package/dist/cjs/components/XAdkProvider/compound/styles.js +16 -0
- package/dist/cjs/components/XAdkProvider/compound/styles.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.d.ts +4 -0
- package/dist/cjs/components/XAdkProvider/context/ChatSenderStateContext.js.map +2 -2
- package/dist/cjs/components/XAdkProvider/index.js +9 -8
- package/dist/cjs/components/XAdkProvider/index.js.map +2 -2
- package/dist/cjs/components/XAdkSender/InlineTagInput.js +223 -24
- package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +2 -2
- package/dist/cjs/components/XAdkSender/InputTags.js.map +2 -2
- package/dist/cjs/components/XAdkSender/index.js +21 -55
- package/dist/cjs/components/XAdkSender/index.js.map +2 -2
- package/dist/cjs/components/XAdkSender/styles.js +13 -0
- package/dist/cjs/components/XAdkSender/styles.js.map +2 -2
- package/dist/cjs/hooks/useADKChat.js +5 -1
- package/dist/cjs/hooks/useADKChat.js.map +2 -2
- package/dist/cjs/index.d.ts +4 -3
- package/dist/cjs/index.js +14 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/presets/xgroup/index.d.ts +1 -0
- package/dist/cjs/presets/xgroup/index.js +2 -0
- package/dist/cjs/presets/xgroup/index.js.map +2 -2
- package/dist/cjs/presets/xgroup/knowledgeReference.d.ts +17 -0
- package/dist/cjs/presets/xgroup/knowledgeReference.js +160 -0
- package/dist/cjs/presets/xgroup/knowledgeReference.js.map +7 -0
- package/dist/cjs/presets/xgroup/preset.d.ts +3 -1
- package/dist/cjs/presets/xgroup/preset.js +17 -0
- package/dist/cjs/presets/xgroup/preset.js.map +2 -2
- package/dist/cjs/presets/xgroup/strategies.d.ts +1 -1
- package/dist/cjs/presets/xgroup/strategies.js +3 -5
- package/dist/cjs/presets/xgroup/strategies.js.map +2 -2
- package/dist/cjs/types/ChatStrategies.d.ts +3 -1
- package/dist/cjs/types/ChatStrategies.js.map +1 -1
- package/dist/cjs/types/XAdkChatbot.d.ts +18 -0
- package/dist/cjs/types/XAdkChatbot.js.map +1 -1
- package/dist/cjs/types/XAdkSender.d.ts +10 -3
- package/dist/cjs/types/XAdkSender.js.map +1 -1
- package/dist/cjs/utils/markdownResource.d.ts +5 -2
- package/dist/cjs/utils/markdownResource.js +57 -5
- package/dist/cjs/utils/markdownResource.js.map +2 -2
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +11 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +147 -25
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js +2 -2
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/index.d.ts +2 -2
- package/dist/esm/components/XAdkChatbot/index.js +36 -10
- package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/DefaultLayout.d.ts +7 -2
- package/dist/esm/components/XAdkProvider/compound/DefaultLayout.js +64 -16
- package/dist/esm/components/XAdkProvider/compound/DefaultLayout.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/Sender.d.ts +2 -1
- package/dist/esm/components/XAdkProvider/compound/Sender.js +2 -1
- package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
- package/dist/esm/components/XAdkProvider/compound/styles.d.ts +1 -0
- package/dist/esm/components/XAdkProvider/compound/styles.js +3 -2
- package/dist/esm/components/XAdkProvider/compound/styles.js.map +1 -1
- package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.d.ts +4 -0
- package/dist/esm/components/XAdkProvider/context/ChatSenderStateContext.js.map +1 -1
- package/dist/esm/components/XAdkProvider/index.js +6 -2
- package/dist/esm/components/XAdkProvider/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/InlineTagInput.js +209 -10
- package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -1
- package/dist/esm/components/XAdkSender/InputTags.js +1 -0
- package/dist/esm/components/XAdkSender/InputTags.js.map +1 -1
- package/dist/esm/components/XAdkSender/index.js +25 -58
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/styles.js +1 -1
- package/dist/esm/components/XAdkSender/styles.js.map +1 -1
- package/dist/esm/hooks/useADKChat.js +8 -2
- package/dist/esm/hooks/useADKChat.js.map +1 -1
- package/dist/esm/index.d.ts +4 -3
- package/dist/esm/index.js +3 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/presets/xgroup/index.d.ts +1 -0
- package/dist/esm/presets/xgroup/index.js +1 -0
- package/dist/esm/presets/xgroup/index.js.map +1 -1
- package/dist/esm/presets/xgroup/knowledgeReference.d.ts +17 -0
- package/dist/esm/presets/xgroup/knowledgeReference.js +94 -0
- package/dist/esm/presets/xgroup/knowledgeReference.js.map +1 -0
- package/dist/esm/presets/xgroup/preset.d.ts +3 -1
- package/dist/esm/presets/xgroup/preset.js +15 -0
- package/dist/esm/presets/xgroup/preset.js.map +1 -1
- package/dist/esm/presets/xgroup/strategies.d.ts +1 -1
- package/dist/esm/presets/xgroup/strategies.js +3 -3
- package/dist/esm/presets/xgroup/strategies.js.map +1 -1
- package/dist/esm/types/ChatStrategies.d.ts +3 -1
- package/dist/esm/types/ChatStrategies.js.map +1 -1
- package/dist/esm/types/XAdkChatbot.d.ts +18 -0
- package/dist/esm/types/XAdkChatbot.js.map +1 -1
- package/dist/esm/types/XAdkSender.d.ts +10 -3
- package/dist/esm/types/XAdkSender.js.map +1 -1
- package/dist/esm/utils/markdownResource.d.ts +5 -2
- package/dist/esm/utils/markdownResource.js +66 -1
- package/dist/esm/utils/markdownResource.js.map +1 -1
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -10,12 +10,13 @@ import type { XAdkSenderProps, XAdkSenderHandle } from "../../../types";
|
|
|
10
10
|
* ```tsx
|
|
11
11
|
* <XAdkProvider url="..." token="...">
|
|
12
12
|
* <XAdkProvider.Sender
|
|
13
|
-
* allowUpload={true}
|
|
14
13
|
* clearBtnShow={true}
|
|
15
14
|
* uploadRequest={myUploadHandler}
|
|
16
15
|
* />
|
|
17
16
|
* </XAdkProvider>
|
|
18
17
|
* ```
|
|
18
|
+
*
|
|
19
|
+
* 提示:如需内置上传按钮与拖拽上传,请使用 XAdkProvider.DefaultLayout 并设置 allowUpload。
|
|
19
20
|
*/
|
|
20
21
|
export interface XAdkSenderCompoundProps extends Partial<Omit<XAdkSenderProps, "loading" | "onSubmit" | "onStop" | "onClear">> {
|
|
21
22
|
/** 额外的样式 */
|
|
@@ -14,12 +14,13 @@ import { useChatActions } from "../context/ChatActionContext";
|
|
|
14
14
|
* ```tsx
|
|
15
15
|
* <XAdkProvider url="..." token="...">
|
|
16
16
|
* <XAdkProvider.Sender
|
|
17
|
-
* allowUpload={true}
|
|
18
17
|
* clearBtnShow={true}
|
|
19
18
|
* uploadRequest={myUploadHandler}
|
|
20
19
|
* />
|
|
21
20
|
* </XAdkProvider>
|
|
22
21
|
* ```
|
|
22
|
+
*
|
|
23
|
+
* 提示:如需内置上传按钮与拖拽上传,请使用 XAdkProvider.DefaultLayout 并设置 allowUpload。
|
|
23
24
|
*/
|
|
24
25
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
25
26
|
var Sender = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","forwardRef","XAdkSender","useChatSenderState","useChatActions","jsx","_jsx","Sender","props","ref","_useChatSenderState","loading","uploadRequest","senderValue","setSenderValue","_useChatActions","chat","stopChat","clearChat","_objectSpread","value","onChange","onSubmit","onStop","onClear","displayName"],"sources":["../../../../../src/components/XAdkProvider/compound/Sender.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport XAdkSender from \"@/components/XAdkSender\";\nimport { useChatSenderState } from \"../context/ChatSenderStateContext\";\nimport { useChatActions } from \"../context/ChatActionContext\";\nimport type { XAdkSenderProps, XAdkSenderHandle } from \"@/types\";\n\n/**\n * XAdkProvider.Sender - 输入框组件\n *\n * 从 Context 获取聊天动作并提供输入界面\n * 基于 XAdkSender 组件实现\n *\n * @example\n * ```tsx\n * <XAdkProvider url=\"...\" token=\"...\">\n * <XAdkProvider.Sender\n *
|
|
1
|
+
{"version":3,"names":["React","forwardRef","XAdkSender","useChatSenderState","useChatActions","jsx","_jsx","Sender","props","ref","_useChatSenderState","loading","uploadRequest","senderValue","setSenderValue","_useChatActions","chat","stopChat","clearChat","_objectSpread","value","onChange","onSubmit","onStop","onClear","displayName"],"sources":["../../../../../src/components/XAdkProvider/compound/Sender.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport XAdkSender from \"@/components/XAdkSender\";\nimport { useChatSenderState } from \"../context/ChatSenderStateContext\";\nimport { useChatActions } from \"../context/ChatActionContext\";\nimport type { XAdkSenderProps, XAdkSenderHandle } from \"@/types\";\n\n/**\n * XAdkProvider.Sender - 输入框组件\n *\n * 从 Context 获取聊天动作并提供输入界面\n * 基于 XAdkSender 组件实现\n *\n * @example\n * ```tsx\n * <XAdkProvider url=\"...\" token=\"...\">\n * <XAdkProvider.Sender\n * clearBtnShow={true}\n * uploadRequest={myUploadHandler}\n * />\n * </XAdkProvider>\n * ```\n *\n * 提示:如需内置上传按钮与拖拽上传,请使用 XAdkProvider.DefaultLayout 并设置 allowUpload。\n */\nexport interface XAdkSenderCompoundProps extends Partial<\n Omit<XAdkSenderProps, \"loading\" | \"onSubmit\" | \"onStop\" | \"onClear\">\n> {\n /** 额外的样式 */\n style?: React.CSSProperties;\n /** 额外的类名 */\n className?: string;\n}\n\nconst Sender = forwardRef<XAdkSenderHandle, XAdkSenderCompoundProps>(\n (props, ref) => {\n const { loading, uploadRequest, senderValue, setSenderValue } = useChatSenderState();\n const { chat, stopChat, clearChat } = useChatActions();\n\n return (\n <XAdkSender\n ref={ref}\n {...props}\n loading={loading}\n value={senderValue}\n onChange={setSenderValue}\n onSubmit={chat}\n onStop={stopChat}\n onClear={clearChat}\n uploadRequest={uploadRequest}\n />\n );\n },\n);\n\nSender.displayName = \"XAdkProvider.Sender\";\n\nexport default Sender;\n"],"mappings":";AAAA,OAAOA,KAAK,IAAIC,UAAU,QAAQ,OAAO;AACzC,OAAOC,UAAU;AACjB,SAASC,kBAAkB;AAC3B,SAASC,cAAc;;AAGvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAjBA,SAAAC,GAAA,IAAAC,IAAA;AA2BA,IAAMC,MAAM,gBAAGN,UAAU,CACvB,UAACO,KAAK,EAAEC,GAAG,EAAK;EACd,IAAAC,mBAAA,GAAgEP,kBAAkB,CAAC,CAAC;IAA5EQ,OAAO,GAAAD,mBAAA,CAAPC,OAAO;IAAEC,aAAa,GAAAF,mBAAA,CAAbE,aAAa;IAAEC,WAAW,GAAAH,mBAAA,CAAXG,WAAW;IAAEC,cAAc,GAAAJ,mBAAA,CAAdI,cAAc;EAC3D,IAAAC,eAAA,GAAsCX,cAAc,CAAC,CAAC;IAA9CY,IAAI,GAAAD,eAAA,CAAJC,IAAI;IAAEC,QAAQ,GAAAF,eAAA,CAARE,QAAQ;IAAEC,SAAS,GAAAH,eAAA,CAATG,SAAS;EAEjC,oBACEZ,IAAA,CAACJ,UAAU,EAAAiB,aAAA,CAAAA,aAAA;IACTV,GAAG,EAAEA;EAAI,GACLD,KAAK;IACTG,OAAO,EAAEA,OAAQ;IACjBS,KAAK,EAAEP,WAAY;IACnBQ,QAAQ,EAAEP,cAAe;IACzBQ,QAAQ,EAAEN,IAAK;IACfO,MAAM,EAAEN,QAAS;IACjBO,OAAO,EAAEN,SAAU;IACnBN,aAAa,EAAEA;EAAc,EAC9B,CAAC;AAEN,CACF,CAAC;AAEDL,MAAM,CAACkB,WAAW,GAAG,qBAAqB;AAE1C,eAAelB,MAAM"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import _taggedTemplateLiteral from "@babel/runtime/helpers/esm/taggedTemplateLiteral";
|
|
2
|
-
var _templateObject, _templateObject2;
|
|
2
|
+
var _templateObject, _templateObject2, _templateObject3;
|
|
3
3
|
import { css } from "@emotion/css";
|
|
4
4
|
import { withBasicStyles } from "../../../styles/common";
|
|
5
5
|
export var useStyles = withBasicStyles(function () {
|
|
6
6
|
return {
|
|
7
7
|
logoText: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n font-size: 30px;\n line-height: 36px;\n font-weight: 800;\n width: 100%;\n min-width: 330px;\n margin-top: 30px;\n color: transparent;\n background: linear-gradient(to right, #ff69b4, #4169e1);\n background-clip: text;\n width: 0;\n overflow: hidden;\n text-overflow: unset;\n white-space: nowrap;\n animation: typewiriter 1s forwards;\n "]))),
|
|
8
|
-
sendWrapper: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n width: 100%;\n align-self: center;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n "])))
|
|
8
|
+
sendWrapper: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n width: 100%;\n align-self: center;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n "]))),
|
|
9
|
+
uploadButton: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n border: 0;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border-radius: 50%;\n color: #6b7280;\n transition: background 0.2s;\n\n &:hover {\n background: rgba(0, 0, 0, 0.04);\n }\n "])))
|
|
9
10
|
};
|
|
10
11
|
});
|
|
11
12
|
//# sourceMappingURL=styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["css","withBasicStyles","useStyles","logoText","_templateObject","_taggedTemplateLiteral","sendWrapper","_templateObject2"],"sources":["../../../../../src/components/XAdkProvider/compound/styles.tsx"],"sourcesContent":["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n logoText: css`\n font-size: 30px;\n line-height: 36px;\n font-weight: 800;\n width: 100%;\n min-width: 330px;\n margin-top: 30px;\n color: transparent;\n background: linear-gradient(to right, #ff69b4, #4169e1);\n background-clip: text;\n width: 0;\n overflow: hidden;\n text-overflow: unset;\n white-space: nowrap;\n animation: typewiriter 1s forwards;\n `,\n\n sendWrapper: css`\n position: relative;\n width: 100%;\n align-self: center;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n `,\n}));\n"],"mappings":";;AAAA,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,eAAe;AAExB,OAAO,IAAMC,SAAS,GAAGD,eAAe,CAAC;EAAA,OAAO;IAC9CE,QAAQ,EAAEH,GAAG,CAAAI,eAAA,KAAAA,eAAA,GAAAC,sBAAA,wYAeZ;IAEDC,WAAW,EAAEN,GAAG,CAAAO,gBAAA,KAAAA,gBAAA,GAAAF,sBAAA;
|
|
1
|
+
{"version":3,"names":["css","withBasicStyles","useStyles","logoText","_templateObject","_taggedTemplateLiteral","sendWrapper","_templateObject2","uploadButton","_templateObject3"],"sources":["../../../../../src/components/XAdkProvider/compound/styles.tsx"],"sourcesContent":["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n logoText: css`\n font-size: 30px;\n line-height: 36px;\n font-weight: 800;\n width: 100%;\n min-width: 330px;\n margin-top: 30px;\n color: transparent;\n background: linear-gradient(to right, #ff69b4, #4169e1);\n background-clip: text;\n width: 0;\n overflow: hidden;\n text-overflow: unset;\n white-space: nowrap;\n animation: typewiriter 1s forwards;\n `,\n\n sendWrapper: css`\n position: relative;\n width: 100%;\n align-self: center;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n `,\n\n uploadButton: css`\n border: 0;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n border-radius: 50%;\n color: #6b7280;\n transition: background 0.2s;\n\n &:hover {\n background: rgba(0, 0, 0, 0.04);\n }\n `,\n}));\n"],"mappings":";;AAAA,SAASA,GAAG,QAAQ,cAAc;AAClC,SAASC,eAAe;AAExB,OAAO,IAAMC,SAAS,GAAGD,eAAe,CAAC;EAAA,OAAO;IAC9CE,QAAQ,EAAEH,GAAG,CAAAI,eAAA,KAAAA,eAAA,GAAAC,sBAAA,wYAeZ;IAEDC,WAAW,EAAEN,GAAG,CAAAO,gBAAA,KAAAA,gBAAA,GAAAF,sBAAA,wIAKf;IAEDG,YAAY,EAAER,GAAG,CAAAS,gBAAA,KAAAA,gBAAA,GAAAJ,sBAAA;EAgBnB,CAAC;AAAA,CAAC,CAAC"}
|
|
@@ -7,6 +7,10 @@ import type { UploadRequestFn } from "../../../types";
|
|
|
7
7
|
export interface ChatSenderStateContextType {
|
|
8
8
|
loading: boolean;
|
|
9
9
|
uploadRequest?: UploadRequestFn;
|
|
10
|
+
/** Provider 级上传开关,默认布局可直接继承 config.allowUpload。 */
|
|
11
|
+
allowUpload: boolean;
|
|
12
|
+
/** Provider 级拖拽上传开关,默认布局仍可通过同名 prop 局部覆盖。 */
|
|
13
|
+
draggable: boolean;
|
|
10
14
|
/** Sender 输入框受控值 */
|
|
11
15
|
senderValue: string;
|
|
12
16
|
/** 更新 Sender 输入框值 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createContext","useContext","ChatSenderStateContext","useChatSenderState","context","Error"],"sources":["../../../../../src/components/XAdkProvider/context/ChatSenderStateContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport type { UploadRequestFn } from \"@/types\";\n\n/**\n * Sender 专用状态 Context\n * 仅包含 Sender 需要的字段,避免 messages 变化导致 Sender 重渲染和焦点丢失\n */\nexport interface ChatSenderStateContextType {\n loading: boolean;\n uploadRequest?: UploadRequestFn;\n /** Sender 输入框受控值 */\n senderValue: string;\n /** 更新 Sender 输入框值 */\n setSenderValue: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const ChatSenderStateContext
|
|
1
|
+
{"version":3,"names":["createContext","useContext","ChatSenderStateContext","useChatSenderState","context","Error"],"sources":["../../../../../src/components/XAdkProvider/context/ChatSenderStateContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport type { UploadRequestFn } from \"@/types\";\n\n/**\n * Sender 专用状态 Context\n * 仅包含 Sender 需要的字段,避免 messages 变化导致 Sender 重渲染和焦点丢失\n */\nexport interface ChatSenderStateContextType {\n loading: boolean;\n uploadRequest?: UploadRequestFn;\n /** Provider 级上传开关,默认布局可直接继承 config.allowUpload。 */\n allowUpload: boolean;\n /** Provider 级拖拽上传开关,默认布局仍可通过同名 prop 局部覆盖。 */\n draggable: boolean;\n /** Sender 输入框受控值 */\n senderValue: string;\n /** 更新 Sender 输入框值 */\n setSenderValue: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const ChatSenderStateContext =\n createContext<ChatSenderStateContextType | null>(null);\n\nexport const useChatSenderState = () => {\n const context = useContext(ChatSenderStateContext);\n if (!context) {\n throw new Error(\"useChatSenderState must be used within XAdkProvider\");\n }\n return context;\n};\n"],"mappings":"AAAA,SAAgBA,aAAa,EAAEC,UAAU,QAAQ,OAAO;;AAGxD;AACA;AACA;AACA;;AAcA,OAAO,IAAMC,sBAAsB,gBACjCF,aAAa,CAAoC,IAAI,CAAC;AAExD,OAAO,IAAMG,kBAAkB,GAAG,SAArBA,kBAAkBA,CAAA,EAAS;EACtC,IAAMC,OAAO,GAAGH,UAAU,CAACC,sBAAsB,CAAC;EAClD,IAAI,CAACE,OAAO,EAAE;IACZ,MAAM,IAAIC,KAAK,CAAC,qDAAqD,CAAC;EACxE;EACA,OAAOD,OAAO;AAChB,CAAC"}
|
|
@@ -62,7 +62,7 @@ import { mergeChatStrategies, resolvePresetUploadRequest } from "../../presets/x
|
|
|
62
62
|
* </XAdkProvider>
|
|
63
63
|
*/
|
|
64
64
|
var XAdkProviderComponent = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
65
|
-
var _config$showFeedback, _config$uploadRequest;
|
|
65
|
+
var _config$showFeedback, _config$allowUpload, _config$draggable, _config$uploadRequest;
|
|
66
66
|
var _ref$url = _ref.url,
|
|
67
67
|
url = _ref$url === void 0 ? window.location.origin : _ref$url,
|
|
68
68
|
token = _ref.token,
|
|
@@ -134,6 +134,8 @@ var XAdkProviderComponent = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
134
134
|
setStateDelta = _data$setStateDelta === void 0 ? function () {} : _data$setStateDelta;
|
|
135
135
|
var showFeedback = (_config$showFeedback = config === null || config === void 0 ? void 0 : config.showFeedback) !== null && _config$showFeedback !== void 0 ? _config$showFeedback : true;
|
|
136
136
|
var onFileClick = config === null || config === void 0 ? void 0 : config.onFileClick;
|
|
137
|
+
var allowUpload = (_config$allowUpload = config === null || config === void 0 ? void 0 : config.allowUpload) !== null && _config$allowUpload !== void 0 ? _config$allowUpload : false;
|
|
138
|
+
var draggable = (_config$draggable = config === null || config === void 0 ? void 0 : config.draggable) !== null && _config$draggable !== void 0 ? _config$draggable : true;
|
|
137
139
|
var presetUploadRequest = useMemo(function () {
|
|
138
140
|
return resolvePresetUploadRequest(preset !== null && preset !== void 0 ? preset : config === null || config === void 0 ? void 0 : config.preset, {
|
|
139
141
|
url: url,
|
|
@@ -224,10 +226,12 @@ var XAdkProviderComponent = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
224
226
|
return {
|
|
225
227
|
loading: loading,
|
|
226
228
|
uploadRequest: uploadRequest,
|
|
229
|
+
allowUpload: allowUpload,
|
|
230
|
+
draggable: draggable,
|
|
227
231
|
senderValue: senderValue,
|
|
228
232
|
setSenderValue: setSenderValue
|
|
229
233
|
};
|
|
230
|
-
}, [loading, uploadRequest, senderValue]);
|
|
234
|
+
}, [loading, uploadRequest, allowUpload, draggable, senderValue]);
|
|
231
235
|
return /*#__PURE__*/_jsx(ConfigProvider, {
|
|
232
236
|
theme: {
|
|
233
237
|
token: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","forwardRef","useImperativeHandle","useMemo","useState","ConfigProvider","XProvider","ChatStateContext","ChatActionContext","SessionContext","ChatSenderStateContext","useADKChat","primaryBlue","cssVarStyle","mergeChatStrategies","resolvePresetUploadRequest","XAdkProviderComponent","_ref","ref","_config$showFeedback","_config$uploadRequest","_ref$url","url","window","location","origin","token","config","preset","strategies","chatData","_ref$providerId","providerId","onSuccess","onError","onMessage","onStream","children","mergedStrategies","_objectSpread","internalData","enabled","data","appInfo","startChat","stopChat","reChat","clearChat","suggestChat","confirmFnCall","deleteSession","updateSession","currentSessionId","sessionPagination","sessionList","messages","loading","prologue","suggestions","initialized","setCurrentSession","setMessages","_data$likeMessage","likeMessage","_asyncToGenerator","_regeneratorRuntime","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","stop","_data$setStateDelta","setStateDelta","showFeedback","onFileClick","presetUploadRequest","appNo","uploadRequest","getAppInfo","getMessages","getSessions","chatStateValue","chatActionValue","chat","sessionValue","_useState","_useState2","_slicedToArray","senderValue","setSenderValue","senderStateValue","_jsx","theme","colorPrimary","appTheme","Provider","value","style","display","height","width","position","displayName","Header","Sidebar","Messages","Sender","Chatbot","Welcome","DefaultLayout","jsx","XAdkProvider"],"sources":["../../../../src/components/XAdkProvider/index.tsx"],"sourcesContent":["import React, { forwardRef, useImperativeHandle, useMemo, useState } from \"react\";\nimport { ConfigProvider } from \"antd\";\nimport { XProvider } from \"@ant-design/x\";\nimport { ChatStateContext } from \"./context/ChatStateContext\";\nimport { ChatActionContext } from \"./context/ChatActionContext\";\nimport { SessionContext } from \"./context/SessionContext\";\nimport { ChatSenderStateContext } from \"./context/ChatSenderStateContext\";\nimport useADKChat from \"@/hooks/useADKChat\";\nimport { primaryBlue } from \"@/styles/common\";\nimport { cssVarStyle } from \"@/styles/tokens\";\nimport type {\n XAdkProviderProps,\n XAdkProviderHandle,\n XAdkProviderConfig,\n} from \"@/types/XAdkProvider\";\nimport type { ChatHookResult } from \"@/types/ChatHook\";\nimport {\n mergeChatStrategies,\n resolvePresetUploadRequest,\n} from \"@/presets/xgroup\";\n\n/**\n * XAdkProvider Props (扩展版)\n *\n * 支持两种使用方式:\n * 1. 标准协议: 提供 url/token/config,使用内置 useADKChat\n * 2. 自定义协议: 提供 chatData,使用自己的 Hook\n */\nexport interface XAdkProviderPropsExtended extends Omit<\n XAdkProviderProps,\n \"url\" | \"token\" | \"config\"\n> {\n /**\n * 选项 A: 使用标准协议 (内置 useADKChat)\n */\n url?: string;\n token: string;\n config?: XAdkProviderConfig;\n\n /**\n * 选项 B: 使用自定义 Hook 数据\n * 如果提供此参数,将忽略 url/token/config\n *\n * @example\n * // GraphQL 协议\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n *\n * @example\n * // WebSocket 协议\n * const chatData = useWebSocketChat({ url: 'ws://...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n */\n chatData?: ChatHookResult;\n\n children: React.ReactNode;\n}\n\n/**\n * XAdkProvider - AI 聊天 SDK 核心 Provider\n *\n * 采用 Compound Components 架构:\n * - 只负责数据和状态管理\n * - 不包含 UI 布局\n * - 通过 Context 向子组件提供数据\n * - 支持完全自定义的组件组合\n * - 支持协议解耦,可使用自定义 Hook\n *\n * @example\n * // 基础用法 - 标准协议\n * <XAdkProvider url=\"...\" token=\"...\" config={...}>\n * <XAdkProvider.Chatbot />\n * </XAdkProvider>\n *\n * @example\n * // 自定义协议 - GraphQL\n * function App() {\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * return (\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n * );\n * }\n *\n * @example\n * // 自定义布局\n * <XAdkProvider url=\"...\" token=\"...\">\n * <div style={{ display: 'flex' }}>\n * <XAdkProvider.Sidebar />\n * <div>\n * <XAdkProvider.Messages />\n * <XAdkProvider.Sender />\n * </div>\n * </div>\n * </XAdkProvider>\n */\nconst XAdkProviderComponent = forwardRef<\n XAdkProviderHandle,\n XAdkProviderPropsExtended\n>(\n (\n {\n url = window.location.origin,\n token,\n config,\n preset,\n strategies,\n chatData, // 自定义 Hook 数据\n providerId = \"defaultId\",\n onSuccess,\n onError,\n onMessage,\n onStream,\n children,\n },\n ref,\n ) => {\n const mergedStrategies = useMemo(\n () =>\n mergeChatStrategies(\n preset ?? config?.preset,\n {\n ...config?.strategies,\n ...strategies,\n },\n ),\n [preset, strategies, config?.preset, config?.strategies],\n );\n\n // 内置 Hook 数据 (仅在没有提供 chatData 时调用)\n const internalData = useADKChat({\n url,\n token: token || \"\",\n config: config || {},\n strategies: mergedStrategies,\n onError,\n onSuccess,\n onMessage,\n onStream,\n // 仅在提供了 url 和 token 时才初始化\n enabled: !chatData && !!url && !!token,\n });\n\n // 使用外部数据或内部数据\n const data = chatData || internalData;\n\n // 解构数据\n const {\n appInfo,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n confirmFnCall,\n deleteSession,\n updateSession,\n currentSessionId,\n sessionPagination,\n sessionList,\n messages,\n loading,\n prologue,\n suggestions,\n initialized,\n setCurrentSession,\n setMessages,\n likeMessage = async () => false,\n setStateDelta = () => {},\n } = data;\n\n const showFeedback = config?.showFeedback ?? true;\n const onFileClick = config?.onFileClick;\n const presetUploadRequest = useMemo(\n () =>\n resolvePresetUploadRequest(preset ?? config?.preset, {\n url,\n token,\n appNo: config?.appNo,\n }),\n [preset, config?.preset, url, token, config?.appNo],\n );\n const uploadRequest = config?.uploadRequest ?? presetUploadRequest;\n\n // 暴露 API 给 ref\n useImperativeHandle(\n ref,\n () => ({\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n getAppInfo: () => appInfo,\n getMessages: () => messages,\n getSessions: () => sessionList,\n setMessages,\n setCurrentSession,\n setStateDelta,\n }),\n [\n appInfo,\n messages,\n sessionList,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n setMessages,\n setCurrentSession,\n setStateDelta,\n ],\n );\n\n // 状态 Context Value - 使用 useMemo 避免不必要的 rerender\n const chatStateValue = useMemo(\n () => ({\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n url,\n token,\n showFeedback,\n onFileClick,\n uploadRequest,\n strategies: mergedStrategies,\n }),\n [\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n url,\n token,\n showFeedback,\n onFileClick,\n uploadRequest,\n mergedStrategies,\n ],\n );\n\n // 动作 Context Value - 函数引用稳定,不需要每次都创建新对象\n const chatActionValue = useMemo(\n () => ({\n chat: startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n }),\n [\n startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n ],\n );\n\n // 会话 Context Value\n const sessionValue = useMemo(\n () => ({\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n }),\n [\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n ],\n );\n\n // Sender 输入框受控状态\n const [senderValue, setSenderValue] = useState(\"\");\n\n // Sender 专用状态 — 不包含 messages,避免轮询更新消息时导致 Sender 重渲染和焦点丢失\n const senderStateValue = useMemo(\n () => ({\n loading,\n uploadRequest,\n senderValue,\n setSenderValue,\n }),\n [loading, uploadRequest, senderValue],\n );\n\n return (\n <ConfigProvider\n theme={{\n token: {\n colorPrimary: appInfo?.appTheme || primaryBlue,\n },\n }}\n >\n <XProvider>\n <ChatStateContext.Provider value={chatStateValue}>\n <ChatActionContext.Provider value={chatActionValue}>\n <SessionContext.Provider value={sessionValue}>\n <ChatSenderStateContext.Provider value={senderStateValue}>\n <div\n style={{\n ...cssVarStyle,\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n } as React.CSSProperties}\n >\n {children}\n </div>\n </ChatSenderStateContext.Provider>\n </SessionContext.Provider>\n </ChatActionContext.Provider>\n </ChatStateContext.Provider>\n </XProvider>\n </ConfigProvider>\n );\n },\n);\n\nXAdkProviderComponent.displayName = \"XAdkProvider\";\n\n// 导入 Compound Components\nimport Header from \"./compound/Header\";\nimport Sidebar from \"./compound/Sidebar\";\nimport Messages from \"./compound/Messages\";\nimport Sender from \"./compound/Sender\";\nimport Chatbot from \"./compound/Chatbot\";\nimport Welcome from \"./compound/Welcome\";\nimport DefaultLayout from \"./compound/DefaultLayout\";\n\n// 导出时会挂载 Compound Components\nconst XAdkProvider = XAdkProviderComponent as typeof XAdkProviderComponent & {\n Header: typeof Header;\n Sidebar: typeof Sidebar;\n Messages: typeof Messages;\n Sender: typeof Sender;\n Chatbot: typeof Chatbot;\n Welcome: typeof Welcome;\n DefaultLayout: typeof DefaultLayout;\n};\n\n// 挂载 Compound Components\nXAdkProvider.Header = Header;\nXAdkProvider.Sidebar = Sidebar;\nXAdkProvider.Messages = Messages;\nXAdkProvider.Sender = Sender;\nXAdkProvider.Chatbot = Chatbot;\nXAdkProvider.DefaultLayout = DefaultLayout;\nXAdkProvider.Welcome = Welcome;\n\nexport default XAdkProvider;\n"],"mappings":";;;;AAAA,OAAOA,KAAK,IAAIC,UAAU,EAAEC,mBAAmB,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,OAAO;AACjF,SAASC,cAAc,QAAQ,MAAM;AACrC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,gBAAgB;AACzB,SAASC,iBAAiB;AAC1B,SAASC,cAAc;AACvB,SAASC,sBAAsB;AAC/B,OAAOC,UAAU;AACjB,SAASC,WAAW;AACpB,SAASC,WAAW;AAOpB,SACEC,mBAAmB,EACnBC,0BAA0B;;AAG5B;AACA;AACA;AACA;AACA;AACA;AACA;;AAmCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMC,qBAAqB,gBAAGf,UAAU,CAItC,UAAAgB,IAAA,EAeEC,GAAG,EACA;EAAA,IAAAC,oBAAA,EAAAC,qBAAA;EAAA,IAAAC,QAAA,GAAAJ,IAAA,CAdDK,GAAG;IAAHA,GAAG,GAAAD,QAAA,cAAGE,MAAM,CAACC,QAAQ,CAACC,MAAM,GAAAJ,QAAA;IAC5BK,KAAK,GAAAT,IAAA,CAALS,KAAK;IACLC,MAAM,GAAAV,IAAA,CAANU,MAAM;IACNC,MAAM,GAAAX,IAAA,CAANW,MAAM;IACNC,UAAU,GAAAZ,IAAA,CAAVY,UAAU;IACVC,QAAQ,GAAAb,IAAA,CAARa,QAAQ;IAAAC,eAAA,GAAAd,IAAA,CACRe,UAAU;IAAVA,UAAU,GAAAD,eAAA,cAAG,WAAW,GAAAA,eAAA;IACxBE,SAAS,GAAAhB,IAAA,CAATgB,SAAS;IACTC,OAAO,GAAAjB,IAAA,CAAPiB,OAAO;IACPC,SAAS,GAAAlB,IAAA,CAATkB,SAAS;IACTC,QAAQ,GAAAnB,IAAA,CAARmB,QAAQ;IACRC,QAAQ,GAAApB,IAAA,CAARoB,QAAQ;EAIV,IAAMC,gBAAgB,GAAGnC,OAAO,CAC9B;IAAA,OACEW,mBAAmB,CACjBc,MAAM,aAANA,MAAM,cAANA,MAAM,GAAID,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEC,MAAM,EAAAW,aAAA,CAAAA,aAAA,KAEnBZ,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEE,UAAU,GAClBA,UAAU,CAEjB,CAAC;EAAA,GACH,CAACD,MAAM,EAAEC,UAAU,EAAEF,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEC,MAAM,EAAED,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEE,UAAU,CACzD,CAAC;;EAED;EACA,IAAMW,YAAY,GAAG7B,UAAU,CAAC;IAC9BW,GAAG,EAAHA,GAAG;IACHI,KAAK,EAAEA,KAAK,IAAI,EAAE;IAClBC,MAAM,EAAEA,MAAM,IAAI,CAAC,CAAC;IACpBE,UAAU,EAAES,gBAAgB;IAC5BJ,OAAO,EAAPA,OAAO;IACPD,SAAS,EAATA,SAAS;IACTE,SAAS,EAATA,SAAS;IACTC,QAAQ,EAARA,QAAQ;IACR;IACAK,OAAO,EAAE,CAACX,QAAQ,IAAI,CAAC,CAACR,GAAG,IAAI,CAAC,CAACI;EACnC,CAAC,CAAC;;EAEF;EACA,IAAMgB,IAAI,GAAGZ,QAAQ,IAAIU,YAAY;;EAErC;EACA,IACEG,OAAO,GAqBLD,IAAI,CArBNC,OAAO;IACPC,SAAS,GAoBPF,IAAI,CApBNE,SAAS;IACTC,QAAQ,GAmBNH,IAAI,CAnBNG,QAAQ;IACRC,MAAM,GAkBJJ,IAAI,CAlBNI,MAAM;IACNC,SAAS,GAiBPL,IAAI,CAjBNK,SAAS;IACTC,WAAW,GAgBTN,IAAI,CAhBNM,WAAW;IACXC,aAAa,GAeXP,IAAI,CAfNO,aAAa;IACbC,aAAa,GAcXR,IAAI,CAdNQ,aAAa;IACbC,aAAa,GAaXT,IAAI,CAbNS,aAAa;IACbC,gBAAgB,GAYdV,IAAI,CAZNU,gBAAgB;IAChBC,iBAAiB,GAWfX,IAAI,CAXNW,iBAAiB;IACjBC,WAAW,GAUTZ,IAAI,CAVNY,WAAW;IACXC,QAAQ,GASNb,IAAI,CATNa,QAAQ;IACRC,OAAO,GAQLd,IAAI,CARNc,OAAO;IACPC,QAAQ,GAONf,IAAI,CAPNe,QAAQ;IACRC,WAAW,GAMThB,IAAI,CANNgB,WAAW;IACXC,WAAW,GAKTjB,IAAI,CALNiB,WAAW;IACXC,iBAAiB,GAIflB,IAAI,CAJNkB,iBAAiB;IACjBC,WAAW,GAGTnB,IAAI,CAHNmB,WAAW;IAAAC,iBAAA,GAGTpB,IAAI,CAFNqB,WAAW;IAAXA,WAAW,GAAAD,iBAAA,2BAAAE,iBAAA,eAAAC,mBAAA,GAAAC,IAAA,CAAG,SAAAC,QAAA;MAAA,OAAAF,mBAAA,GAAAG,IAAA,UAAAC,SAAAC,QAAA;QAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;UAAA;YAAA,OAAAF,QAAA,CAAAG,MAAA,WAAY,KAAK;UAAA;UAAA;YAAA,OAAAH,QAAA,CAAAI,IAAA;QAAA;MAAA,GAAAP,OAAA;IAAA,MAAAL,iBAAA;IAAAa,mBAAA,GAE7BjC,IAAI,CADNkC,aAAa;IAAbA,aAAa,GAAAD,mBAAA,cAAG,YAAM,CAAC,CAAC,GAAAA,mBAAA;EAG1B,IAAME,YAAY,IAAA1D,oBAAA,GAAGQ,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEkD,YAAY,cAAA1D,oBAAA,cAAAA,oBAAA,GAAI,IAAI;EACjD,IAAM2D,WAAW,GAAGnD,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEmD,WAAW;EACvC,IAAMC,mBAAmB,GAAG5E,OAAO,CACjC;IAAA,OACEY,0BAA0B,CAACa,MAAM,aAANA,MAAM,cAANA,MAAM,GAAID,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEC,MAAM,EAAE;MACnDN,GAAG,EAAHA,GAAG;MACHI,KAAK,EAALA,KAAK;MACLsD,KAAK,EAAErD,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEqD;IACjB,CAAC,CAAC;EAAA,GACJ,CAACpD,MAAM,EAAED,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEC,MAAM,EAAEN,GAAG,EAAEI,KAAK,EAAEC,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEqD,KAAK,CACpD,CAAC;EACD,IAAMC,aAAa,IAAA7D,qBAAA,GAAGO,MAAM,aAANA,MAAM,uBAANA,MAAM,CAAEsD,aAAa,cAAA7D,qBAAA,cAAAA,qBAAA,GAAI2D,mBAAmB;;EAElE;EACA7E,mBAAmB,CACjBgB,GAAG,EACH;IAAA,OAAO;MACL0B,SAAS,EAATA,SAAS;MACTC,QAAQ,EAARA,QAAQ;MACRC,MAAM,EAANA,MAAM;MACNC,SAAS,EAATA,SAAS;MACTC,WAAW,EAAXA,WAAW;MACXE,aAAa,EAAbA,aAAa;MACbC,aAAa,EAAbA,aAAa;MACb+B,UAAU,EAAE,SAAAA,WAAA;QAAA,OAAMvC,OAAO;MAAA;MACzBwC,WAAW,EAAE,SAAAA,YAAA;QAAA,OAAM5B,QAAQ;MAAA;MAC3B6B,WAAW,EAAE,SAAAA,YAAA;QAAA,OAAM9B,WAAW;MAAA;MAC9BO,WAAW,EAAXA,WAAW;MACXD,iBAAiB,EAAjBA,iBAAiB;MACjBgB,aAAa,EAAbA;IACF,CAAC;EAAA,CAAC,EACF,CACEjC,OAAO,EACPY,QAAQ,EACRD,WAAW,EACXV,SAAS,EACTC,QAAQ,EACRC,MAAM,EACNC,SAAS,EACTC,WAAW,EACXE,aAAa,EACbC,aAAa,EACbU,WAAW,EACXD,iBAAiB,EACjBgB,aAAa,CAEjB,CAAC;;EAED;EACA,IAAMS,cAAc,GAAGlF,OAAO,CAC5B;IAAA,OAAO;MACLoD,QAAQ,EAARA,QAAQ;MACRC,OAAO,EAAPA,OAAO;MACPJ,gBAAgB,EAAhBA,gBAAgB;MAChBK,QAAQ,EAARA,QAAQ;MACRC,WAAW,EAAXA,WAAW;MACXf,OAAO,EAAPA,OAAO;MACPgB,WAAW,EAAXA,WAAW;MACXrC,GAAG,EAAHA,GAAG;MACHI,KAAK,EAALA,KAAK;MACLmD,YAAY,EAAZA,YAAY;MACZC,WAAW,EAAXA,WAAW;MACXG,aAAa,EAAbA,aAAa;MACbpD,UAAU,EAAES;IACd,CAAC;EAAA,CAAC,EACF,CACEiB,QAAQ,EACRC,OAAO,EACPJ,gBAAgB,EAChBK,QAAQ,EACRC,WAAW,EACXf,OAAO,EACPgB,WAAW,EACXrC,GAAG,EACHI,KAAK,EACLmD,YAAY,EACZC,WAAW,EACXG,aAAa,EACb3C,gBAAgB,CAEpB,CAAC;;EAED;EACA,IAAMgD,eAAe,GAAGnF,OAAO,CAC7B;IAAA,OAAO;MACLoF,IAAI,EAAE3C,SAAS;MACfC,QAAQ,EAARA,QAAQ;MACRE,SAAS,EAATA,SAAS;MACTD,MAAM,EAANA,MAAM;MACNE,WAAW,EAAXA,WAAW;MACXC,aAAa,EAAbA,aAAa;MACbY,WAAW,EAAXA,WAAW;MACXE,WAAW,EAAXA,WAAW;MACXa,aAAa,EAAbA;IACF,CAAC;EAAA,CAAC,EACF,CACEhC,SAAS,EACTC,QAAQ,EACRE,SAAS,EACTD,MAAM,EACNE,WAAW,EACXC,aAAa,EACbY,WAAW,EACXE,WAAW,EACXa,aAAa,CAEjB,CAAC;;EAED;EACA,IAAMY,YAAY,GAAGrF,OAAO,CAC1B;IAAA,OAAO;MACLmD,WAAW,EAAXA,WAAW;MACXD,iBAAiB,EAAjBA,iBAAiB;MACjBH,aAAa,EAAbA,aAAa;MACbC,aAAa,EAAbA,aAAa;MACbS,iBAAiB,EAAjBA;IACF,CAAC;EAAA,CAAC,EACF,CACEN,WAAW,EACXD,iBAAiB,EACjBH,aAAa,EACbC,aAAa,EACbS,iBAAiB,CAErB,CAAC;;EAED;EACA,IAAA6B,SAAA,GAAsCrF,QAAQ,CAAC,EAAE,CAAC;IAAAsF,UAAA,GAAAC,cAAA,CAAAF,SAAA;IAA3CG,WAAW,GAAAF,UAAA;IAAEG,cAAc,GAAAH,UAAA;;EAElC;EACA,IAAMI,gBAAgB,GAAG3F,OAAO,CAC9B;IAAA,OAAO;MACLqD,OAAO,EAAPA,OAAO;MACPyB,aAAa,EAAbA,aAAa;MACbW,WAAW,EAAXA,WAAW;MACXC,cAAc,EAAdA;IACF,CAAC;EAAA,CAAC,EACF,CAACrC,OAAO,EAAEyB,aAAa,EAAEW,WAAW,CACtC,CAAC;EAED,oBACEG,IAAA,CAAC1F,cAAc;IACb2F,KAAK,EAAE;MACLtE,KAAK,EAAE;QACLuE,YAAY,EAAE,CAAAtD,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEuD,QAAQ,KAAItF;MACrC;IACF,CAAE;IAAAyB,QAAA,eAEF0D,IAAA,CAACzF,SAAS;MAAA+B,QAAA,eACR0D,IAAA,CAACxF,gBAAgB,CAAC4F,QAAQ;QAACC,KAAK,EAAEf,cAAe;QAAAhD,QAAA,eAC/C0D,IAAA,CAACvF,iBAAiB,CAAC2F,QAAQ;UAACC,KAAK,EAAEd,eAAgB;UAAAjD,QAAA,eACjD0D,IAAA,CAACtF,cAAc,CAAC0F,QAAQ;YAACC,KAAK,EAAEZ,YAAa;YAAAnD,QAAA,eAC3C0D,IAAA,CAACrF,sBAAsB,CAACyF,QAAQ;cAACC,KAAK,EAAEN,gBAAiB;cAAAzD,QAAA,eACvD0D,IAAA;gBACEM,KAAK,EAAA9D,aAAA,CAAAA,aAAA,KACA1B,WAAW;kBACdyF,OAAO,EAAE,MAAM;kBACfC,MAAM,EAAE,MAAM;kBACdC,KAAK,EAAE,MAAM;kBACbC,QAAQ,EAAE;gBAAU,EACG;gBAAApE,QAAA,EAExBA;cAAQ,CACN;YAAC,CACyB;UAAC,CACX;QAAC,CACA;MAAC,CACJ;IAAC,CACnB;EAAC,CACE,CAAC;AAErB,CACF,CAAC;AAEDrB,qBAAqB,CAAC0F,WAAW,GAAG,cAAc;;AAElD;AACA,OAAOC,MAAM;AACb,OAAOC,OAAO;AACd,OAAOC,QAAQ;AACf,OAAOC,MAAM;AACb,OAAOC,OAAO;AACd,OAAOC,OAAO;AACd,OAAOC,aAAa;;AAEpB;AAAA,SAAAC,GAAA,IAAAnB,IAAA;AACA,IAAMoB,YAAY,GAAGnG,qBAQpB;;AAED;AACAmG,YAAY,CAACR,MAAM,GAAGA,MAAM;AAC5BQ,YAAY,CAACP,OAAO,GAAGA,OAAO;AAC9BO,YAAY,CAACN,QAAQ,GAAGA,QAAQ;AAChCM,YAAY,CAACL,MAAM,GAAGA,MAAM;AAC5BK,YAAY,CAACJ,OAAO,GAAGA,OAAO;AAC9BI,YAAY,CAACF,aAAa,GAAGA,aAAa;AAC1CE,YAAY,CAACH,OAAO,GAAGA,OAAO;AAE9B,eAAeG,YAAY"}
|
|
1
|
+
{"version":3,"names":["React","forwardRef","useImperativeHandle","useMemo","useState","ConfigProvider","XProvider","ChatStateContext","ChatActionContext","SessionContext","ChatSenderStateContext","useADKChat","primaryBlue","cssVarStyle","mergeChatStrategies","resolvePresetUploadRequest","XAdkProviderComponent","_ref","ref","_config$showFeedback","_config$allowUpload","_config$draggable","_config$uploadRequest","_ref$url","url","window","location","origin","token","config","preset","strategies","chatData","_ref$providerId","providerId","onSuccess","onError","onMessage","onStream","children","mergedStrategies","_objectSpread","internalData","enabled","data","appInfo","startChat","stopChat","reChat","clearChat","suggestChat","confirmFnCall","deleteSession","updateSession","currentSessionId","sessionPagination","sessionList","messages","loading","prologue","suggestions","initialized","setCurrentSession","setMessages","_data$likeMessage","likeMessage","_asyncToGenerator","_regeneratorRuntime","mark","_callee","wrap","_callee$","_context","prev","next","abrupt","stop","_data$setStateDelta","setStateDelta","showFeedback","onFileClick","allowUpload","draggable","presetUploadRequest","appNo","uploadRequest","getAppInfo","getMessages","getSessions","chatStateValue","chatActionValue","chat","sessionValue","_useState","_useState2","_slicedToArray","senderValue","setSenderValue","senderStateValue","_jsx","theme","colorPrimary","appTheme","Provider","value","style","display","height","width","position","displayName","Header","Sidebar","Messages","Sender","Chatbot","Welcome","DefaultLayout","jsx","XAdkProvider"],"sources":["../../../../src/components/XAdkProvider/index.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useState,\n} from \"react\";\nimport { ConfigProvider } from \"antd\";\nimport { XProvider } from \"@ant-design/x\";\nimport { ChatStateContext } from \"./context/ChatStateContext\";\nimport { ChatActionContext } from \"./context/ChatActionContext\";\nimport { SessionContext } from \"./context/SessionContext\";\nimport { ChatSenderStateContext } from \"./context/ChatSenderStateContext\";\nimport useADKChat from \"@/hooks/useADKChat\";\nimport { primaryBlue } from \"@/styles/common\";\nimport { cssVarStyle } from \"@/styles/tokens\";\nimport type {\n XAdkProviderProps,\n XAdkProviderHandle,\n XAdkProviderConfig,\n} from \"@/types/XAdkProvider\";\nimport type { ChatHookResult } from \"@/types/ChatHook\";\nimport {\n mergeChatStrategies,\n resolvePresetUploadRequest,\n} from \"@/presets/xgroup\";\n\n/**\n * XAdkProvider Props (扩展版)\n *\n * 支持两种使用方式:\n * 1. 标准协议: 提供 url/token/config,使用内置 useADKChat\n * 2. 自定义协议: 提供 chatData,使用自己的 Hook\n */\nexport interface XAdkProviderPropsExtended extends Omit<\n XAdkProviderProps,\n \"url\" | \"token\" | \"config\"\n> {\n /**\n * 选项 A: 使用标准协议 (内置 useADKChat)\n */\n url?: string;\n token: string;\n config?: XAdkProviderConfig;\n\n /**\n * 选项 B: 使用自定义 Hook 数据\n * 如果提供此参数,将忽略 url/token/config\n *\n * @example\n * // GraphQL 协议\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n *\n * @example\n * // WebSocket 协议\n * const chatData = useWebSocketChat({ url: 'ws://...' });\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n */\n chatData?: ChatHookResult;\n\n children: React.ReactNode;\n}\n\n/**\n * XAdkProvider - AI 聊天 SDK 核心 Provider\n *\n * 采用 Compound Components 架构:\n * - 只负责数据和状态管理\n * - 不包含 UI 布局\n * - 通过 Context 向子组件提供数据\n * - 支持完全自定义的组件组合\n * - 支持协议解耦,可使用自定义 Hook\n *\n * @example\n * // 基础用法 - 标准协议\n * <XAdkProvider url=\"...\" token=\"...\" config={...}>\n * <XAdkProvider.Chatbot />\n * </XAdkProvider>\n *\n * @example\n * // 自定义协议 - GraphQL\n * function App() {\n * const chatData = useMyGraphQLChat({ endpoint: '...' });\n * return (\n * <XAdkProvider chatData={chatData}>\n * <XAdkProvider.DefaultLayout />\n * </XAdkProvider>\n * );\n * }\n *\n * @example\n * // 自定义布局\n * <XAdkProvider url=\"...\" token=\"...\">\n * <div style={{ display: 'flex' }}>\n * <XAdkProvider.Sidebar />\n * <div>\n * <XAdkProvider.Messages />\n * <XAdkProvider.Sender />\n * </div>\n * </div>\n * </XAdkProvider>\n */\nconst XAdkProviderComponent = forwardRef<\n XAdkProviderHandle,\n XAdkProviderPropsExtended\n>(\n (\n {\n url = window.location.origin,\n token,\n config,\n preset,\n strategies,\n chatData, // 自定义 Hook 数据\n providerId = \"defaultId\",\n onSuccess,\n onError,\n onMessage,\n onStream,\n children,\n },\n ref,\n ) => {\n const mergedStrategies = useMemo(\n () =>\n mergeChatStrategies(preset ?? config?.preset, {\n ...config?.strategies,\n ...strategies,\n }),\n [preset, strategies, config?.preset, config?.strategies],\n );\n\n // 内置 Hook 数据 (仅在没有提供 chatData 时调用)\n const internalData = useADKChat({\n url,\n token: token || \"\",\n config: config || {},\n strategies: mergedStrategies,\n onError,\n onSuccess,\n onMessage,\n onStream,\n // 仅在提供了 url 和 token 时才初始化\n enabled: !chatData && !!url && !!token,\n });\n\n // 使用外部数据或内部数据\n const data = chatData || internalData;\n\n // 解构数据\n const {\n appInfo,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n confirmFnCall,\n deleteSession,\n updateSession,\n currentSessionId,\n sessionPagination,\n sessionList,\n messages,\n loading,\n prologue,\n suggestions,\n initialized,\n setCurrentSession,\n setMessages,\n likeMessage = async () => false,\n setStateDelta = () => {},\n } = data;\n\n const showFeedback = config?.showFeedback ?? true;\n const onFileClick = config?.onFileClick;\n const allowUpload = config?.allowUpload ?? false;\n const draggable = config?.draggable ?? true;\n const presetUploadRequest = useMemo(\n () =>\n resolvePresetUploadRequest(preset ?? config?.preset, {\n url,\n token,\n appNo: config?.appNo,\n }),\n [preset, config?.preset, url, token, config?.appNo],\n );\n const uploadRequest = config?.uploadRequest ?? presetUploadRequest;\n\n // 暴露 API 给 ref\n useImperativeHandle(\n ref,\n () => ({\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n getAppInfo: () => appInfo,\n getMessages: () => messages,\n getSessions: () => sessionList,\n setMessages,\n setCurrentSession,\n setStateDelta,\n }),\n [\n appInfo,\n messages,\n sessionList,\n startChat,\n stopChat,\n reChat,\n clearChat,\n suggestChat,\n deleteSession,\n updateSession,\n setMessages,\n setCurrentSession,\n setStateDelta,\n ],\n );\n\n // 状态 Context Value - 使用 useMemo 避免不必要的 rerender\n const chatStateValue = useMemo(\n () => ({\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n url,\n token,\n showFeedback,\n onFileClick,\n uploadRequest,\n strategies: mergedStrategies,\n }),\n [\n messages,\n loading,\n currentSessionId,\n prologue,\n suggestions,\n appInfo,\n initialized,\n url,\n token,\n showFeedback,\n onFileClick,\n uploadRequest,\n mergedStrategies,\n ],\n );\n\n // 动作 Context Value - 函数引用稳定,不需要每次都创建新对象\n const chatActionValue = useMemo(\n () => ({\n chat: startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n }),\n [\n startChat,\n stopChat,\n clearChat,\n reChat,\n suggestChat,\n confirmFnCall,\n setMessages,\n likeMessage,\n setStateDelta,\n ],\n );\n\n // 会话 Context Value\n const sessionValue = useMemo(\n () => ({\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n }),\n [\n sessionList,\n sessionPagination,\n deleteSession,\n updateSession,\n setCurrentSession,\n ],\n );\n\n // Sender 输入框受控状态\n const [senderValue, setSenderValue] = useState(\"\");\n\n // Sender 专用状态 — 不包含 messages,避免轮询更新消息时导致 Sender 重渲染和焦点丢失\n const senderStateValue = useMemo(\n () => ({\n loading,\n uploadRequest,\n allowUpload,\n draggable,\n senderValue,\n setSenderValue,\n }),\n [loading, uploadRequest, allowUpload, draggable, senderValue],\n );\n\n return (\n <ConfigProvider\n theme={{\n token: {\n colorPrimary: appInfo?.appTheme || primaryBlue,\n },\n }}\n >\n <XProvider>\n <ChatStateContext.Provider value={chatStateValue}>\n <ChatActionContext.Provider value={chatActionValue}>\n <SessionContext.Provider value={sessionValue}>\n <ChatSenderStateContext.Provider value={senderStateValue}>\n <div\n style={\n {\n ...cssVarStyle,\n display: \"flex\",\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n } as React.CSSProperties\n }\n >\n {children}\n </div>\n </ChatSenderStateContext.Provider>\n </SessionContext.Provider>\n </ChatActionContext.Provider>\n </ChatStateContext.Provider>\n </XProvider>\n </ConfigProvider>\n );\n },\n);\n\nXAdkProviderComponent.displayName = \"XAdkProvider\";\n\n// 导入 Compound Components\nimport Header from \"./compound/Header\";\nimport Sidebar from \"./compound/Sidebar\";\nimport Messages from \"./compound/Messages\";\nimport Sender from \"./compound/Sender\";\nimport Chatbot from \"./compound/Chatbot\";\nimport Welcome from \"./compound/Welcome\";\nimport DefaultLayout from \"./compound/DefaultLayout\";\n\n// 导出时会挂载 Compound Components\nconst XAdkProvider = XAdkProviderComponent as typeof XAdkProviderComponent & {\n Header: typeof Header;\n Sidebar: typeof Sidebar;\n Messages: typeof Messages;\n Sender: typeof Sender;\n Chatbot: typeof Chatbot;\n Welcome: typeof Welcome;\n DefaultLayout: typeof DefaultLayout;\n};\n\n// 挂载 Compound Components\nXAdkProvider.Header = Header;\nXAdkProvider.Sidebar = Sidebar;\nXAdkProvider.Messages = Messages;\nXAdkProvider.Sender = Sender;\nXAdkProvider.Chatbot = Chatbot;\nXAdkProvider.DefaultLayout = DefaultLayout;\nXAdkProvider.Welcome = Welcome;\n\nexport default XAdkProvider;\n"],"mappings":"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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
|
|
1
2
|
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
2
|
-
import
|
|
3
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
|
+
import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useImperativeHandle, useRef, useState } from "react";
|
|
3
5
|
import { createRoot } from "react-dom/client";
|
|
4
6
|
import { useStyles } from "./styles";
|
|
7
|
+
import { parseMarkdownResourceLinksAsParts } from "../../utils/markdownResource";
|
|
5
8
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
6
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
10
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -27,6 +30,8 @@ var toRawOffset = function toRawOffset(text, plainOffset) {
|
|
|
27
30
|
}
|
|
28
31
|
return text.length;
|
|
29
32
|
};
|
|
33
|
+
|
|
34
|
+
// 内联标签展示逻辑
|
|
30
35
|
var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
31
36
|
var value = _ref.value,
|
|
32
37
|
mentions = _ref.mentions,
|
|
@@ -46,6 +51,14 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
46
51
|
var lastInsertedCaretRef = useRef(null);
|
|
47
52
|
var savedRangeRef = useRef(null);
|
|
48
53
|
var defaultInputPartsAppliedRef = useRef(false);
|
|
54
|
+
var skipEmptyCleanupOnceRef = useRef(false);
|
|
55
|
+
var structuralCleanupFrameRef = useRef(null);
|
|
56
|
+
var _useState = useState(function () {
|
|
57
|
+
return Boolean(value || mentions.length);
|
|
58
|
+
}),
|
|
59
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
60
|
+
hasContent = _useState2[0],
|
|
61
|
+
setHasContent = _useState2[1];
|
|
49
62
|
var lastEmittedStateRef = useRef({
|
|
50
63
|
value: value,
|
|
51
64
|
mentionIds: mentions.map(function (mention) {
|
|
@@ -110,6 +123,7 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
110
123
|
var emitChange = useCallback(function () {
|
|
111
124
|
var nextValue = getPlainText();
|
|
112
125
|
var nextMentions = getOrderedMentions();
|
|
126
|
+
setHasContent(Boolean(nextValue || nextMentions.length));
|
|
113
127
|
lastEmittedStateRef.current = {
|
|
114
128
|
value: nextValue,
|
|
115
129
|
mentionIds: nextMentions.map(function (mention) {
|
|
@@ -168,6 +182,7 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
168
182
|
span.setAttribute("contenteditable", "false");
|
|
169
183
|
span.setAttribute(MENTION_ATTR, mention.id);
|
|
170
184
|
span.dataset.xadkInlineMentionId = mention.id;
|
|
185
|
+
span.dataset.xadkInlineMentionType = mention.type;
|
|
171
186
|
span.className = styles.inlineTag;
|
|
172
187
|
if (renderMention) {
|
|
173
188
|
var root = createRoot(span);
|
|
@@ -282,6 +297,34 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
282
297
|
}
|
|
283
298
|
return null;
|
|
284
299
|
};
|
|
300
|
+
var moveCursorAroundMention = useCallback(function (mention, direction) {
|
|
301
|
+
var editor = editorRef.current;
|
|
302
|
+
var selection = window.getSelection();
|
|
303
|
+
if (!editor || !selection || !editor.contains(mention)) return;
|
|
304
|
+
var range = document.createRange();
|
|
305
|
+
if (direction === "before") {
|
|
306
|
+
var previous = mention.previousSibling;
|
|
307
|
+
if ((previous === null || previous === void 0 ? void 0 : previous.nodeType) === Node.TEXT_NODE) {
|
|
308
|
+
var _previous$textContent;
|
|
309
|
+
range.setStart(previous, ((_previous$textContent = previous.textContent) === null || _previous$textContent === void 0 ? void 0 : _previous$textContent.length) || 0);
|
|
310
|
+
} else {
|
|
311
|
+
range.setStartBefore(mention);
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
var next = mention.nextSibling;
|
|
315
|
+
if ((next === null || next === void 0 ? void 0 : next.nodeType) === Node.TEXT_NODE) {
|
|
316
|
+
var _match;
|
|
317
|
+
var leadingCaretLength = ((_match = (next.textContent || "").match(/^\u200B+/)) === null || _match === void 0 ? void 0 : _match[0].length) || 0;
|
|
318
|
+
range.setStart(next, leadingCaretLength);
|
|
319
|
+
} else {
|
|
320
|
+
range.setStartAfter(mention);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
range.collapse(true);
|
|
324
|
+
selection.removeAllRanges();
|
|
325
|
+
selection.addRange(range);
|
|
326
|
+
savedRangeRef.current = range.cloneRange();
|
|
327
|
+
}, []);
|
|
285
328
|
|
|
286
329
|
// 读取光标在纯文本中的位置,供快捷键搜索词和 Mention 插入位置复用。
|
|
287
330
|
var getOffsetInEditor = useCallback(function () {
|
|
@@ -373,9 +416,68 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
373
416
|
}
|
|
374
417
|
});
|
|
375
418
|
}, []);
|
|
419
|
+
|
|
420
|
+
// Chrome 会把标签前临时输入的文字包进块级节点;文字被删空后,可能留下
|
|
421
|
+
// <div><br></div>。它没有消息语义,却会在 contenteditable 中占据一整行。
|
|
422
|
+
var cleanupEmptyStructuralNodes = useCallback(function () {
|
|
423
|
+
var editor = editorRef.current;
|
|
424
|
+
var selection = window.getSelection();
|
|
425
|
+
if (!editor) return;
|
|
426
|
+
Array.from(editor.children).forEach(function (node) {
|
|
427
|
+
if (node.hasAttribute(MENTION_ATTR)) return;
|
|
428
|
+
if (node.querySelector("[".concat(MENTION_ATTR, "]"))) return;
|
|
429
|
+
if (normalizeText(node.textContent || "")) return;
|
|
430
|
+
var range = selection !== null && selection !== void 0 && selection.rangeCount ? selection.getRangeAt(0) : null;
|
|
431
|
+
var nodeIndex = getNodeIndex(node);
|
|
432
|
+
var containsCursor = Boolean(range && range.collapsed && (range.startContainer === node || node.contains(range.startContainer) || range.startContainer === editor && (range.startOffset === nodeIndex || range.startOffset === nodeIndex + 1)));
|
|
433
|
+
if (containsCursor && selection) {
|
|
434
|
+
// 光标紧邻 contenteditable=false 的 Mention 时,单纯删除 <br> 会让 Chrome
|
|
435
|
+
// 再次生成它。替换成零宽文本锚点,既能承接光标,也不会增加行高。
|
|
436
|
+
var caretNode = createTextNode(CARET_TEXT);
|
|
437
|
+
node.replaceWith(caretNode);
|
|
438
|
+
var nextRange = document.createRange();
|
|
439
|
+
nextRange.setStart(caretNode, CARET_TEXT.length);
|
|
440
|
+
nextRange.collapse(true);
|
|
441
|
+
selection.removeAllRanges();
|
|
442
|
+
selection.addRange(nextRange);
|
|
443
|
+
savedRangeRef.current = nextRange.cloneRange();
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
node.remove();
|
|
447
|
+
});
|
|
448
|
+
}, []);
|
|
449
|
+
useEffect(function () {
|
|
450
|
+
var editor = editorRef.current;
|
|
451
|
+
if (!editor) return;
|
|
452
|
+
|
|
453
|
+
// 某些业务容器会截断 React 委托事件;直接监听编辑器的原生 input,确保删除事务结束后
|
|
454
|
+
// 仍能清理 Chrome 在不可编辑 Mention 前生成的占行 <br>。仅处理 delete*,不影响 Enter 换行。
|
|
455
|
+
var handleNativeDelete = function handleNativeDelete(event) {
|
|
456
|
+
if (!(event instanceof InputEvent)) return;
|
|
457
|
+
if (!event.inputType.startsWith("delete")) return;
|
|
458
|
+
if (structuralCleanupFrameRef.current !== null) {
|
|
459
|
+
window.cancelAnimationFrame(structuralCleanupFrameRef.current);
|
|
460
|
+
}
|
|
461
|
+
structuralCleanupFrameRef.current = window.requestAnimationFrame(function () {
|
|
462
|
+
structuralCleanupFrameRef.current = null;
|
|
463
|
+
cleanupEmptyStructuralNodes();
|
|
464
|
+
cleanupCaretTextNodes();
|
|
465
|
+
});
|
|
466
|
+
};
|
|
467
|
+
editor.addEventListener("input", handleNativeDelete);
|
|
468
|
+
return function () {
|
|
469
|
+
return editor.removeEventListener("input", handleNativeDelete);
|
|
470
|
+
};
|
|
471
|
+
}, [cleanupCaretTextNodes, cleanupEmptyStructuralNodes]);
|
|
376
472
|
var insertMention = useCallback(function (mention, replace) {
|
|
377
473
|
var editor = editorRef.current;
|
|
378
474
|
if (!editor) return;
|
|
475
|
+
// 工具栏/弹窗会先抢走焦点;必须在 focus 之前保存当前 Selection,
|
|
476
|
+
// 否则浏览器新建在输入框开头的 Range 会覆盖最后一次真实光标位置。
|
|
477
|
+
var selectionBeforeFocus = window.getSelection();
|
|
478
|
+
var activeRangeBeforeFocus = selectionBeforeFocus !== null && selectionBeforeFocus !== void 0 && selectionBeforeFocus.rangeCount && editor.contains(selectionBeforeFocus.getRangeAt(0).startContainer) ? selectionBeforeFocus.getRangeAt(0).cloneRange() : null;
|
|
479
|
+
var savedRangeBeforeFocus = savedRangeRef.current && editor.contains(savedRangeRef.current.startContainer) ? savedRangeRef.current.cloneRange() : null;
|
|
480
|
+
var rangeBeforeFocus = activeRangeBeforeFocus || savedRangeBeforeFocus;
|
|
379
481
|
editor.focus();
|
|
380
482
|
latestMentionsRef.current = [].concat(_toConsumableArray(latestMentionsRef.current.filter(function (item) {
|
|
381
483
|
return item.id !== mention.id;
|
|
@@ -385,11 +487,17 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
385
487
|
insertRange = replaceTextRange(replace.start, replace.end);
|
|
386
488
|
cleanupCaretTextNodes();
|
|
387
489
|
}
|
|
490
|
+
// 浏览器会在空 contenteditable 中生成 <div><br> 等占位块。
|
|
491
|
+
// 空编辑器插入首个 Mention 前先清掉这些无语义节点,避免标签被放进第二个视觉行。
|
|
492
|
+
var isSemanticallyEmpty = !getPlainText() && !editor.querySelector("[".concat(MENTION_ATTR, "]"));
|
|
493
|
+
if (isSemanticallyEmpty) {
|
|
494
|
+
editor.innerHTML = "";
|
|
495
|
+
savedRangeRef.current = null;
|
|
496
|
+
insertRange = null;
|
|
497
|
+
}
|
|
388
498
|
var mentionNode = buildMentionNode(mention);
|
|
389
499
|
var caretNode = createTextNode(CARET_TEXT);
|
|
390
|
-
var
|
|
391
|
-
var savedRange = savedRangeRef.current;
|
|
392
|
-
var range = insertRange || (selection !== null && selection !== void 0 && selection.rangeCount && editor.contains(selection.getRangeAt(0).startContainer) ? selection.getRangeAt(0) : savedRange && editor.contains(savedRange.startContainer) ? savedRange : null);
|
|
500
|
+
var range = insertRange || rangeBeforeFocus;
|
|
393
501
|
if (range && editor.contains(range.startContainer)) {
|
|
394
502
|
// 用 DocumentFragment 一次性插入,避免连续 insertNode 导致 mention/caret 顺序被浏览器 Range 状态打乱。
|
|
395
503
|
var fragment = document.createDocumentFragment();
|
|
@@ -410,13 +518,20 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
410
518
|
restoreCursorAfterInsert(caretNode);
|
|
411
519
|
}
|
|
412
520
|
});
|
|
413
|
-
}, [buildMentionNode, cleanupCaretTextNodes, emitChange, replaceTextRange, restoreCursorAfterInsert, setCursorAtTextEnd]);
|
|
521
|
+
}, [buildMentionNode, cleanupCaretTextNodes, emitChange, getPlainText, replaceTextRange, restoreCursorAfterInsert, setCursorAtTextEnd]);
|
|
414
522
|
useEffect(function () {
|
|
415
523
|
document.addEventListener("selectionchange", saveSelectionRange);
|
|
416
524
|
return function () {
|
|
417
525
|
document.removeEventListener("selectionchange", saveSelectionRange);
|
|
418
526
|
};
|
|
419
527
|
}, [saveSelectionRange]);
|
|
528
|
+
useEffect(function () {
|
|
529
|
+
return function () {
|
|
530
|
+
if (structuralCleanupFrameRef.current !== null) {
|
|
531
|
+
window.cancelAnimationFrame(structuralCleanupFrameRef.current);
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
}, []);
|
|
420
535
|
useImperativeHandle(ref, function () {
|
|
421
536
|
return {
|
|
422
537
|
focus: function focus() {
|
|
@@ -437,6 +552,9 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
437
552
|
// 默认片段只在空输入首次挂载时灌入,避免外部重新渲染覆盖用户正在编辑的内容。
|
|
438
553
|
if (!defaultInputPartsAppliedRef.current && defaultInputParts !== null && defaultInputParts !== void 0 && defaultInputParts.length && !value && mentions.length === 0) {
|
|
439
554
|
defaultInputPartsAppliedRef.current = true;
|
|
555
|
+
// emitChange 的受控回写要到下一次 render 才生效;跳过本轮紧随其后的空值清理,
|
|
556
|
+
// 避免刚渲染的默认 Mention 被旧的空 value/mentions 立即移除。
|
|
557
|
+
skipEmptyCleanupOnceRef.current = true;
|
|
440
558
|
renderPartsToEditor(defaultInputParts);
|
|
441
559
|
emitChange();
|
|
442
560
|
return;
|
|
@@ -456,6 +574,7 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
456
574
|
mention: mention
|
|
457
575
|
};
|
|
458
576
|
}))));
|
|
577
|
+
setHasContent(Boolean(value || mentions.length));
|
|
459
578
|
|
|
460
579
|
// 外部主动写入 value/mentions 后,需要在首帧绘制前同步 DOM;若输入区已有焦点,则把光标放在内容末尾。
|
|
461
580
|
var lastTextNode = Array.from(editor.childNodes).reverse().find(function (node) {
|
|
@@ -468,6 +587,10 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
468
587
|
useIsomorphicLayoutEffect(function () {
|
|
469
588
|
var editor = editorRef.current;
|
|
470
589
|
if (!editor) return;
|
|
590
|
+
if (skipEmptyCleanupOnceRef.current) {
|
|
591
|
+
skipEmptyCleanupOnceRef.current = false;
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
471
594
|
if (!value && mentions.length === 0 && editor.childNodes.length > 0) {
|
|
472
595
|
editor.querySelectorAll("[".concat(MENTION_ATTR, "]")).forEach(function (node) {
|
|
473
596
|
var _tagRootMapRef$curren3;
|
|
@@ -477,18 +600,89 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
477
600
|
}
|
|
478
601
|
}, [mentions.length, value]);
|
|
479
602
|
var handleInput = function handleInput() {
|
|
480
|
-
if (!composingRef.current)
|
|
603
|
+
if (!composingRef.current) {
|
|
604
|
+
cleanupEmptyStructuralNodes();
|
|
605
|
+
cleanupCaretTextNodes();
|
|
606
|
+
emitChange();
|
|
607
|
+
|
|
608
|
+
// Chrome 可能在 input 回调返回后才补上用于承接光标的 <br>;下一帧再归一化一次。
|
|
609
|
+
if (structuralCleanupFrameRef.current !== null) {
|
|
610
|
+
window.cancelAnimationFrame(structuralCleanupFrameRef.current);
|
|
611
|
+
}
|
|
612
|
+
structuralCleanupFrameRef.current = window.requestAnimationFrame(function () {
|
|
613
|
+
structuralCleanupFrameRef.current = null;
|
|
614
|
+
cleanupEmptyStructuralNodes();
|
|
615
|
+
cleanupCaretTextNodes();
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
var handlePaste = function handlePaste(event) {
|
|
620
|
+
event.preventDefault();
|
|
621
|
+
var editor = editorRef.current;
|
|
622
|
+
if (!editor) return;
|
|
623
|
+
|
|
624
|
+
// 始终按 text/plain 粘贴,避免消息气泡的背景色等 HTML 样式进入 contenteditable。
|
|
625
|
+
var text = event.clipboardData.getData("text/plain");
|
|
626
|
+
if (!text) return;
|
|
627
|
+
var parts = parseMarkdownResourceLinksAsParts(text);
|
|
628
|
+
var selection = window.getSelection();
|
|
629
|
+
var range = selection !== null && selection !== void 0 && selection.rangeCount && editor.contains(selection.getRangeAt(0).startContainer) ? selection.getRangeAt(0) : null;
|
|
630
|
+
var fragment = document.createDocumentFragment();
|
|
631
|
+
var lastTextNode = null;
|
|
632
|
+
var _iterator = _createForOfIteratorHelper(parts),
|
|
633
|
+
_step;
|
|
634
|
+
try {
|
|
635
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
636
|
+
var part = _step.value;
|
|
637
|
+
if (part.type === "text") {
|
|
638
|
+
lastTextNode = createTextNode(part.text);
|
|
639
|
+
fragment.append(lastTextNode);
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
latestMentionsRef.current = [].concat(_toConsumableArray(latestMentionsRef.current), [part.mention]);
|
|
643
|
+
fragment.append(buildMentionNode(part.mention));
|
|
644
|
+
lastTextNode = createTextNode(CARET_TEXT);
|
|
645
|
+
fragment.append(lastTextNode);
|
|
646
|
+
}
|
|
647
|
+
} catch (err) {
|
|
648
|
+
_iterator.e(err);
|
|
649
|
+
} finally {
|
|
650
|
+
_iterator.f();
|
|
651
|
+
}
|
|
652
|
+
if (range) {
|
|
653
|
+
range.deleteContents();
|
|
654
|
+
range.insertNode(fragment);
|
|
655
|
+
} else {
|
|
656
|
+
editor.append(fragment);
|
|
657
|
+
}
|
|
658
|
+
cleanupCaretTextNodes();
|
|
659
|
+
if (lastTextNode) setCursorAtTextEnd(lastTextNode);
|
|
660
|
+
emitChange();
|
|
481
661
|
};
|
|
482
662
|
var handleKeyDown = function handleKeyDown(event) {
|
|
483
|
-
if (event.key === "
|
|
663
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
484
664
|
var selection = window.getSelection();
|
|
485
665
|
if (selection !== null && selection !== void 0 && selection.rangeCount) {
|
|
486
666
|
var range = selection.getRangeAt(0);
|
|
487
667
|
if (range.collapsed) {
|
|
488
|
-
var targetMention = event.key === "
|
|
668
|
+
var targetMention = event.key === "ArrowLeft" ? getMentionBeforeRange(range) : getMentionAfterRange(range);
|
|
489
669
|
if (targetMention) {
|
|
490
670
|
event.preventDefault();
|
|
491
|
-
|
|
671
|
+
moveCursorAroundMention(targetMention, event.key === "ArrowLeft" ? "before" : "after");
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (event.key === "Backspace" || event.key === "Delete") {
|
|
678
|
+
var _selection = window.getSelection();
|
|
679
|
+
if (_selection !== null && _selection !== void 0 && _selection.rangeCount) {
|
|
680
|
+
var _range = _selection.getRangeAt(0);
|
|
681
|
+
if (_range.collapsed) {
|
|
682
|
+
var _targetMention = event.key === "Backspace" ? getMentionBeforeRange(_range) : getMentionAfterRange(_range);
|
|
683
|
+
if (_targetMention) {
|
|
684
|
+
event.preventDefault();
|
|
685
|
+
removeMentionById(_targetMention.dataset.xadkInlineMentionId || "");
|
|
492
686
|
return;
|
|
493
687
|
}
|
|
494
688
|
}
|
|
@@ -498,7 +692,7 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
498
692
|
};
|
|
499
693
|
|
|
500
694
|
// placeholder 只由受控 value/mentions 派生,避免从 contenteditable DOM 读取导致外部插入 Mention 后状态滞后一帧。
|
|
501
|
-
var showPlaceholder = !
|
|
695
|
+
var showPlaceholder = !hasContent;
|
|
502
696
|
return /*#__PURE__*/_jsxs("div", {
|
|
503
697
|
className: styles.inlineInputWrapper,
|
|
504
698
|
children: [showPlaceholder && placeholder && /*#__PURE__*/_jsx("div", {
|
|
@@ -512,8 +706,11 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
512
706
|
role: "textbox",
|
|
513
707
|
"aria-multiline": "true",
|
|
514
708
|
onInput: handleInput,
|
|
709
|
+
onPaste: handlePaste,
|
|
515
710
|
onKeyDown: handleKeyDown,
|
|
516
711
|
onKeyUp: function onKeyUp(event) {
|
|
712
|
+
cleanupEmptyStructuralNodes();
|
|
713
|
+
cleanupCaretTextNodes();
|
|
517
714
|
saveSelectionRange();
|
|
518
715
|
_onKeyUp === null || _onKeyUp === void 0 || _onKeyUp(event);
|
|
519
716
|
},
|
|
@@ -521,6 +718,8 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
521
718
|
onFocus: saveSelectionRange,
|
|
522
719
|
onCompositionStart: function onCompositionStart() {
|
|
523
720
|
composingRef.current = true;
|
|
721
|
+
// 中文 IME 在 compositionend 前不会触发受控 value 更新;候选输入一出现就应隐藏 placeholder。
|
|
722
|
+
setHasContent(true);
|
|
524
723
|
},
|
|
525
724
|
onCompositionEnd: function onCompositionEnd() {
|
|
526
725
|
composingRef.current = false;
|