@antdv-next/x 0.0.3 → 0.0.4

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/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- import { Fragment, Teleport, Transition, TransitionGroup, computed, createTextVNode, createVNode, defineComponent, inject, isVNode, mergeProps, nextTick, onBeforeUnmount, onMounted, provide, ref, shallowRef, toRefs, unref, useAttrs, useSlots, vShow, watch, withDirectives } from "vue";
1
+ import { Fragment, Teleport, Transition, TransitionGroup, computed, createTextVNode, createVNode, defineComponent, inject, isVNode, mergeProps, nextTick, onBeforeUnmount, onMounted, provide, ref, render, shallowRef, toRefs, unref, useAttrs, useSlots, vShow, watch, withDirectives } from "vue";
2
2
  import { useConfig } from "antdv-next/dist/config-provider/context";
3
- import { Button, Carousel, Cascader, ConfigProvider, Divider, Dropdown, Flex, Image as Image$1, Popover, Progress, Segmented, Skeleton, Spin, TextArea, Tooltip, Typography, Upload, theme } from "antdv-next";
3
+ import { Button, Carousel, Cascader, ConfigProvider, Divider, Dropdown, Flex, Image as Image$1, Input, Popover, Progress, Segmented, Skeleton, Spin, TextArea, Tooltip, Typography, Upload, theme } from "antdv-next";
4
4
  import Icon, { ArrowUpOutlined, AudioMutedOutlined, AudioOutlined, CheckCircleOutlined, CheckOutlined, ClearOutlined, CloseCircleFilled, CloseCircleOutlined, CloseOutlined, CopyOutlined, DislikeFilled, DislikeOutlined, DownloadOutlined, EllipsisOutlined, FileExcelFilled, FileImageFilled, FileMarkdownFilled, FilePdfFilled, FilePptFilled, FileTextFilled, FileWordFilled, FileZipFilled, JavaOutlined, JavaScriptOutlined, LeftOutlined, LikeFilled, LikeOutlined, LoadingOutlined, MinusCircleOutlined, MoonOutlined, MutedOutlined, PlusOutlined, PythonOutlined, RightOutlined, SoundOutlined, SunOutlined, ZoomInOutlined, ZoomOutOutlined } from "@antdv-next/icons";
5
5
  import { Keyframes, unit } from "@antdv-next/cssinjs";
6
6
  import { genStyleUtils, mergeToken } from "@antdv-next/cssinjs/cssinjs-utils";
@@ -10,7 +10,7 @@ import { useResizeObserver } from "@vueuse/core";
10
10
  import { KeyCode, classNames } from "@v-c/util";
11
11
  import mermaid from "mermaid";
12
12
  //#region package.json
13
- var version = "0.0.3";
13
+ var version = "0.0.4";
14
14
  //#endregion
15
15
  //#region components/x-provider/context.ts
16
16
  var XProviderContextKey = Symbol("antdv-next-x-provider-context");
@@ -489,7 +489,7 @@ var style_default$13 = genStyleHooks("Actions", (token) => {
489
489
  }, prepareComponentToken$13);
490
490
  //#endregion
491
491
  //#region components/actions/Actions.tsx
492
- function _isSlot$6(s) {
492
+ function _isSlot$7(s) {
493
493
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
494
494
  }
495
495
  function getMotionTransitionProps(motionName) {
@@ -649,7 +649,7 @@ var XActions = /* @__PURE__ */ defineComponent({
649
649
  attrs.style,
650
650
  props.style
651
651
  ]
652
- }), [transitionProps.value ? createVNode(Transition, transitionProps.value, _isSlot$6(_slot = renderList()) ? _slot : { default: () => [_slot] }) : renderList()]);
652
+ }), [transitionProps.value ? createVNode(Transition, transitionProps.value, _isSlot$7(_slot = renderList()) ? _slot : { default: () => [_slot] }) : renderList()]);
653
653
  };
654
654
  }
655
655
  });
@@ -2165,7 +2165,7 @@ var XFileCard = /* @__PURE__ */ defineComponent({
2165
2165
  });
2166
2166
  //#endregion
2167
2167
  //#region components/file-card/List.tsx
2168
- function _isSlot$5(s) {
2168
+ function _isSlot$6(s) {
2169
2169
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
2170
2170
  }
2171
2171
  var XFileCardList = /* @__PURE__ */ defineComponent({
@@ -2333,7 +2333,7 @@ var XFileCardList = /* @__PURE__ */ defineComponent({
2333
2333
  "style": [props.style, splitStyles.value.root],
2334
2334
  "onScroll": checkPing
2335
2335
  }, [
2336
- createVNode(TransitionGroup, { "name": `${compCls.value}-motion` }, _isSlot$5(_slot = list.value.map((item, itemIndex) => {
2336
+ createVNode(TransitionGroup, { "name": `${compCls.value}-motion` }, _isSlot$6(_slot = list.value.map((item, itemIndex) => {
2337
2337
  const { __key, ...fileItem } = item;
2338
2338
  const cardSlots = {
2339
2339
  description: slots.description ? (slotInfo) => slots.description?.({
@@ -2660,7 +2660,7 @@ var FileList_default = /* @__PURE__ */ defineComponent({
2660
2660
  });
2661
2661
  //#endregion
2662
2662
  //#region components/attachments/PlaceholderUploader.tsx
2663
- function _isSlot$4(s) {
2663
+ function _isSlot$5(s) {
2664
2664
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
2665
2665
  }
2666
2666
  var PlaceholderUploader = /* @__PURE__ */ defineComponent({
@@ -2755,7 +2755,7 @@ var PlaceholderUploader = /* @__PURE__ */ defineComponent({
2755
2755
  border: 0,
2756
2756
  background: "transparent"
2757
2757
  }
2758
- }), _isSlot$4(node) ? node : { default: () => [node] })]);
2758
+ }), _isSlot$5(node) ? node : { default: () => [node] })]);
2759
2759
  };
2760
2760
  }
2761
2761
  });
@@ -2872,7 +2872,7 @@ var style_default$11 = genStyleHooks("Attachments", (token) => {
2872
2872
  }, prepareComponentToken$11);
2873
2873
  //#endregion
2874
2874
  //#region components/attachments/index.tsx
2875
- function _isSlot$3(s) {
2875
+ function _isSlot$4(s) {
2876
2876
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
2877
2877
  }
2878
2878
  var XAttachments = /* @__PURE__ */ defineComponent({
@@ -3098,7 +3098,7 @@ var XAttachments = /* @__PURE__ */ defineComponent({
3098
3098
  props.rootClass,
3099
3099
  mergedClasses.value.root
3100
3100
  ]
3101
- }, _isSlot$3(_slot = getPlaceholderNode("drop")) ? _slot : { default: () => [_slot] })]);
3101
+ }, _isSlot$4(_slot = getPlaceholderNode("drop")) ? _slot : { default: () => [_slot] })]);
3102
3102
  };
3103
3103
  const renderNormalMode = () => {
3104
3104
  let _slot2;
@@ -3137,7 +3137,7 @@ var XAttachments = /* @__PURE__ */ defineComponent({
3137
3137
  "getDropContainer": props.getDropContainer || (() => containerRef.value),
3138
3138
  "prefixCls": props.prefixCls,
3139
3139
  "class": [hashId.value, cssVarCls.value]
3140
- }, _isSlot$3(_slot2 = getPlaceholderNode("drop")) ? _slot2 : { default: () => [_slot2] })
3140
+ }, _isSlot$4(_slot2 = getPlaceholderNode("drop")) ? _slot2 : { default: () => [_slot2] })
3141
3141
  ]);
3142
3142
  };
3143
3143
  return () => slots.default ? renderWithChildren() : renderNormalMode();
@@ -4157,7 +4157,7 @@ var XBubble = /* @__PURE__ */ defineComponent({
4157
4157
  });
4158
4158
  //#endregion
4159
4159
  //#region components/bubble/Divider.tsx
4160
- function _isSlot$2(s) {
4160
+ function _isSlot$3(s) {
4161
4161
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
4162
4162
  }
4163
4163
  var XBubbleDivider = /* @__PURE__ */ defineComponent({
@@ -4223,7 +4223,7 @@ var XBubbleDivider = /* @__PURE__ */ defineComponent({
4223
4223
  "class": [`${props.prefixCls}-divider`, props.class],
4224
4224
  "styles": props.styles,
4225
4225
  "classes": props.classes
4226
- }), { contentRender: ({ content }) => createVNode(Divider, props.dividerProps, _isSlot$2(content) ? content : { default: () => [content] }) });
4226
+ }), { contentRender: ({ content }) => createVNode(Divider, props.dividerProps, _isSlot$3(content) ? content : { default: () => [content] }) });
4227
4227
  }
4228
4228
  });
4229
4229
  //#endregion
@@ -5545,7 +5545,7 @@ function useGroupable(groupable, items) {
5545
5545
  }
5546
5546
  //#endregion
5547
5547
  //#region components/conversations/Item.tsx
5548
- function _isSlot$1(s) {
5548
+ function _isSlot$2(s) {
5549
5549
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
5550
5550
  }
5551
5551
  var stopPropagation = (event) => {
@@ -5686,14 +5686,14 @@ var ConversationsItem = /* @__PURE__ */ defineComponent({
5686
5686
  }
5687
5687
  }, [
5688
5688
  hasRenderableNode$6(iconNode) && createVNode("div", { "class": `${props.prefixCls}-icon` }, [iconNode]),
5689
- createVNode(Typography.Text, { "class": `${props.prefixCls}-label` }, _isSlot$1(labelNode) ? labelNode : { default: () => [labelNode] }),
5689
+ createVNode(Typography.Text, { "class": `${props.prefixCls}-label` }, _isSlot$2(labelNode) ? labelNode : { default: () => [labelNode] }),
5690
5690
  !disabled && props.menu && createVNode("div", { "onClick": stopPropagation }, [createVNode(Dropdown, {
5691
5691
  "menu": menuProps.value,
5692
5692
  "placement": props.direction === "rtl" ? "bottomLeft" : "bottomRight",
5693
5693
  "trigger": ["click"],
5694
5694
  "disabled": disabled,
5695
5695
  "getPopupContainer": menuProps.value?.getPopupContainer
5696
- }, _isSlot$1(_slot = renderMenuTrigger(props.info)) ? _slot : { default: () => [_slot] })])
5696
+ }, _isSlot$2(_slot = renderMenuTrigger(props.info)) ? _slot : { default: () => [_slot] })])
5697
5697
  ]);
5698
5698
  };
5699
5699
  }
@@ -7040,10 +7040,6 @@ var ActionButton = /* @__PURE__ */ defineComponent({
7040
7040
  variant: {
7041
7041
  type: String,
7042
7042
  default: void 0
7043
- },
7044
- class: {
7045
- type: String,
7046
- default: void 0
7047
7043
  }
7048
7044
  },
7049
7045
  setup(props, { attrs }) {
@@ -7066,7 +7062,7 @@ var ActionButton = /* @__PURE__ */ defineComponent({
7066
7062
  "disabled": mergedDisabled.value,
7067
7063
  "class": [
7068
7064
  prefixCls,
7069
- props.class,
7065
+ attrs.class,
7070
7066
  { [`${prefixCls}-disabled`]: mergedDisabled.value }
7071
7067
  ],
7072
7068
  "onClick": (e) => {
@@ -7177,6 +7173,811 @@ var SendButton_default = /* @__PURE__ */ defineComponent({
7177
7173
  }
7178
7174
  });
7179
7175
  //#endregion
7176
+ //#region components/sender/context.ts
7177
+ var SenderContextKey = Symbol("sender-context");
7178
+ function useSenderContext() {
7179
+ return inject(SenderContextKey, computed(() => ({})));
7180
+ }
7181
+ function provideSenderContext(value) {
7182
+ provide(SenderContextKey, value);
7183
+ }
7184
+ //#endregion
7185
+ //#region components/sender/components/Skill.tsx
7186
+ function _isSlot$1(s) {
7187
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
7188
+ }
7189
+ var Skill_default = /* @__PURE__ */ defineComponent({
7190
+ name: "SenderSkill",
7191
+ props: {
7192
+ prefixCls: {
7193
+ type: String,
7194
+ required: true
7195
+ },
7196
+ skill: {
7197
+ type: Object,
7198
+ required: true
7199
+ },
7200
+ removeSkill: {
7201
+ type: Function,
7202
+ required: true
7203
+ }
7204
+ },
7205
+ setup(props) {
7206
+ const componentCls = computed(() => `${props.prefixCls}-skill`);
7207
+ const closeNode = computed(() => {
7208
+ const closable = props.skill.closable;
7209
+ if (!closable) return null;
7210
+ const config = typeof closable === "boolean" ? {} : closable;
7211
+ const closeIcon = config.closeIcon ?? createVNode(CloseOutlined, { "class": `${componentCls.value}-close-icon` }, null);
7212
+ return createVNode("div", {
7213
+ "class": classNames([`${componentCls.value}-close`, { [`${componentCls.value}-close-disabled`]: config.disabled }]),
7214
+ "role": "button",
7215
+ "aria-label": "Close skill",
7216
+ "tabindex": 0,
7217
+ "onClick": (event) => {
7218
+ if (config.disabled) return;
7219
+ event.stopPropagation();
7220
+ props.removeSkill();
7221
+ config.onClose?.(event);
7222
+ }
7223
+ }, [closeIcon]);
7224
+ });
7225
+ return () => {
7226
+ const mergeTitle = props.skill.title ?? props.skill.value;
7227
+ const titleNode = props.skill.toolTip ? createVNode(Tooltip, props.skill.toolTip, _isSlot$1(mergeTitle) ? mergeTitle : { default: () => [mergeTitle] }) : mergeTitle;
7228
+ return createVNode("div", {
7229
+ "class": `${componentCls.value}-wrapper`,
7230
+ "contenteditable": false
7231
+ }, [createVNode("div", {
7232
+ "class": `${componentCls.value}-tag`,
7233
+ "contenteditable": false,
7234
+ "role": "button",
7235
+ "tabindex": 0
7236
+ }, [createVNode("span", { "class": `${componentCls.value}-tag-text` }, [titleNode]), closeNode.value]), createVNode("div", { "class": `${componentCls.value}-holder` }, null)]);
7237
+ };
7238
+ }
7239
+ });
7240
+ //#endregion
7241
+ //#region components/sender/components/SlotTextArea.tsx
7242
+ var SUPPORTED_INPUT_TYPES = new Set([
7243
+ "input",
7244
+ "select",
7245
+ "custom",
7246
+ "content"
7247
+ ]);
7248
+ function stringifyValue(value) {
7249
+ if (value === void 0 || value === null) return "";
7250
+ if (typeof value === "string") return value;
7251
+ if (typeof value === "number" || typeof value === "boolean") return `${value}`;
7252
+ try {
7253
+ return JSON.stringify(value);
7254
+ } catch {
7255
+ return "";
7256
+ }
7257
+ }
7258
+ function getDefaultSlotValue(config) {
7259
+ if (!config.key) return void 0;
7260
+ const props = config.props ?? {};
7261
+ if (SUPPORTED_INPUT_TYPES.has(config.type)) return props.defaultValue ?? "";
7262
+ return props.value ?? props.label ?? "";
7263
+ }
7264
+ var SlotTextArea_default = /* @__PURE__ */ defineComponent({
7265
+ name: "SlotTextArea",
7266
+ setup(_, { expose }) {
7267
+ const senderCtx = useSenderContext();
7268
+ const editableRef = ref();
7269
+ const slotDomMap = ref(/* @__PURE__ */ new Map());
7270
+ const slotConfigMap = ref(/* @__PURE__ */ new Map());
7271
+ const slotValues = ref({});
7272
+ const mountedDomSet = ref(/* @__PURE__ */ new Set());
7273
+ const skillDomRef = ref(null);
7274
+ const currentSkillRef = ref(void 0);
7275
+ const lastSlotConfigRef = ref(void 0);
7276
+ const lastSkillRef = ref(void 0);
7277
+ const isComposing = ref(false);
7278
+ const keyLock = ref(false);
7279
+ const prefixCls = computed(() => senderCtx.value.prefixCls || "antd-sender");
7280
+ const mergeInputStyle = computed(() => ({
7281
+ ...senderCtx.value.styles?.input,
7282
+ ...getAutoSizeStyle()
7283
+ }));
7284
+ const getAutoSizeStyle = () => {
7285
+ const autoSize = senderCtx.value.autoSize;
7286
+ if (autoSize === true) return { height: "auto" };
7287
+ if (!autoSize || typeof autoSize !== "object") return {};
7288
+ const lineHeight = 22;
7289
+ return {
7290
+ minHeight: autoSize.minRows ? `${autoSize.minRows * lineHeight}px` : void 0,
7291
+ maxHeight: autoSize.maxRows ? `${autoSize.maxRows * lineHeight}px` : void 0,
7292
+ overflowY: "auto"
7293
+ };
7294
+ };
7295
+ const getNodeInfo = (targetNode) => {
7296
+ if (!targetNode?.dataset) return null;
7297
+ const slotKey = targetNode.dataset.slotKey;
7298
+ return {
7299
+ slotKey,
7300
+ skillKey: targetNode.dataset.skillKey,
7301
+ nodeType: targetNode.dataset.nodeType,
7302
+ slotConfig: slotKey ? slotConfigMap.value.get(slotKey) : void 0
7303
+ };
7304
+ };
7305
+ const unmountDom = (container) => {
7306
+ if (!container) return;
7307
+ render(null, container);
7308
+ mountedDomSet.value.delete(container);
7309
+ };
7310
+ const unmountAllPortals = () => {
7311
+ mountedDomSet.value.forEach((container) => {
7312
+ render(null, container);
7313
+ });
7314
+ mountedDomSet.value.clear();
7315
+ };
7316
+ const buildSkillSpan = (key) => {
7317
+ const span = document.createElement("span");
7318
+ span.setAttribute("contenteditable", "false");
7319
+ span.dataset.skillKey = key;
7320
+ span.dataset.placeholder = senderCtx.value.placeholder || "";
7321
+ span.className = `${prefixCls.value}-skill`;
7322
+ return span;
7323
+ };
7324
+ const buildSlotSpan = (key) => {
7325
+ const span = document.createElement("span");
7326
+ span.setAttribute("contenteditable", "false");
7327
+ span.dataset.slotKey = key;
7328
+ span.className = `${prefixCls.value}-slot`;
7329
+ return span;
7330
+ };
7331
+ const buildEditSlotSpan = (config) => {
7332
+ const span = document.createElement("span");
7333
+ span.setAttribute("contenteditable", senderCtx.value.readOnly ? "false" : "true");
7334
+ span.dataset.slotKey = config.key;
7335
+ span.className = `${prefixCls.value}-slot ${prefixCls.value}-slot-content`;
7336
+ return span;
7337
+ };
7338
+ const buildSpaceSpan = (slotKey, position) => {
7339
+ const span = document.createElement("span");
7340
+ span.setAttribute("contenteditable", "false");
7341
+ span.dataset.slotKey = slotKey;
7342
+ span.dataset.nodeType = "nbsp";
7343
+ span.className = `${prefixCls.value}-slot-${position} ${prefixCls.value}-slot-no-width`;
7344
+ span.textContent = "\xA0";
7345
+ return span;
7346
+ };
7347
+ const getNodeTextValue = (node) => {
7348
+ if (node.nodeType === Node.TEXT_NODE) return node.textContent ?? "";
7349
+ if (node.nodeType !== Node.ELEMENT_NODE) return "";
7350
+ const element = node;
7351
+ const nodeInfo = getNodeInfo(element);
7352
+ if (!nodeInfo) return element.innerText || "";
7353
+ if (nodeInfo.skillKey) return "";
7354
+ if (nodeInfo.slotKey) {
7355
+ if (nodeInfo.nodeType === "nbsp") return " ";
7356
+ const config = nodeInfo.slotConfig;
7357
+ if (!config || config.type === "content") return element.innerText || "";
7358
+ const rawValue = slotValues.value[nodeInfo.slotKey];
7359
+ return config.formatResult?.(rawValue) ?? stringifyValue(rawValue);
7360
+ }
7361
+ return element.innerText || "";
7362
+ };
7363
+ const getEditorValue = () => {
7364
+ const editable = editableRef.value;
7365
+ const emptyResult = {
7366
+ value: "",
7367
+ slotConfig: [],
7368
+ skill: void 0
7369
+ };
7370
+ if (!editable) return emptyResult;
7371
+ const childNodes = editable.childNodes;
7372
+ if (childNodes.length === 0) return emptyResult;
7373
+ const textList = [];
7374
+ const currentSlotConfig = [];
7375
+ let currentSkill;
7376
+ childNodes.forEach((node) => {
7377
+ const textValue = getNodeTextValue(node);
7378
+ textList.push(textValue);
7379
+ if (node.nodeType === Node.TEXT_NODE) {
7380
+ if (textValue) currentSlotConfig.push({
7381
+ type: "text",
7382
+ value: textValue
7383
+ });
7384
+ return;
7385
+ }
7386
+ if (node.nodeType === Node.ELEMENT_NODE) {
7387
+ const info = getNodeInfo(node);
7388
+ if (!info) return;
7389
+ if (info.skillKey && currentSkillRef.value) currentSkill = currentSkillRef.value;
7390
+ if (info.slotKey && info.nodeType !== "nbsp") {
7391
+ const cfg = slotConfigMap.value.get(info.slotKey);
7392
+ if (cfg) currentSlotConfig.push({
7393
+ ...cfg,
7394
+ value: textValue
7395
+ });
7396
+ }
7397
+ }
7398
+ });
7399
+ return {
7400
+ value: textList.join(""),
7401
+ slotConfig: currentSlotConfig,
7402
+ skill: currentSkill
7403
+ };
7404
+ };
7405
+ const updateSubmitDisabled = () => {
7406
+ const value = getEditorValue();
7407
+ senderCtx.value.setSubmitDisabled?.(!value.value && value.slotConfig.length === 0 && !value.skill);
7408
+ };
7409
+ const triggerValueChange = (event) => {
7410
+ const value = getEditorValue();
7411
+ senderCtx.value.onChange?.(value.value, event, value.slotConfig, value.skill);
7412
+ updateSkillEmptyStatus(value);
7413
+ updateSubmitDisabled();
7414
+ };
7415
+ const updateSlot = (key, value, event) => {
7416
+ slotValues.value = {
7417
+ ...slotValues.value,
7418
+ [key]: value
7419
+ };
7420
+ const config = slotConfigMap.value.get(key);
7421
+ const dom = slotDomMap.value.get(key);
7422
+ if (config && dom && config.type !== "content") renderSlot(config, dom);
7423
+ triggerValueChange(event);
7424
+ };
7425
+ const buildSelectMenuItems = (options) => {
7426
+ return (options ?? []).map((option) => ({
7427
+ label: option,
7428
+ key: option
7429
+ }));
7430
+ };
7431
+ const renderSlot = (config, slotDom) => {
7432
+ if (!("key" in config) || !config.key) return;
7433
+ const slotValue = slotValues.value[config.key];
7434
+ let node = null;
7435
+ switch (config.type) {
7436
+ case "input":
7437
+ node = createVNode(Input, {
7438
+ "class": `${prefixCls.value}-slot-input`,
7439
+ "placeholder": config.props?.placeholder,
7440
+ "value": slotValue ?? "",
7441
+ "size": "small",
7442
+ "variant": "borderless",
7443
+ "readonly": senderCtx.value.readOnly,
7444
+ "disabled": senderCtx.value.disabled,
7445
+ "onKeydown": onInternalKeyDown,
7446
+ "onChange": (e) => {
7447
+ updateSlot(config.key, e?.target?.value ?? "", e);
7448
+ }
7449
+ }, null);
7450
+ break;
7451
+ case "select": {
7452
+ const displayValue = stringifyValue(slotValue);
7453
+ node = createVNode(Dropdown, {
7454
+ "disabled": senderCtx.value.readOnly || senderCtx.value.disabled,
7455
+ "trigger": ["click"],
7456
+ "menu": {
7457
+ items: buildSelectMenuItems(config.props?.options),
7458
+ selectable: true,
7459
+ selectedKeys: displayValue ? [displayValue] : [],
7460
+ onSelect: ({ key, domEvent }) => {
7461
+ updateSlot(config.key, key, domEvent);
7462
+ }
7463
+ }
7464
+ }, { default: () => [createVNode("span", { "class": classNames([`${prefixCls.value}-slot-select`, {
7465
+ placeholder: !displayValue,
7466
+ [`${prefixCls.value}-slot-select-selector-value`]: !!displayValue
7467
+ }]) }, [createVNode("span", {
7468
+ "data-placeholder": config.props?.placeholder,
7469
+ "class": `${prefixCls.value}-slot-select-value`
7470
+ }, [displayValue]), createVNode("span", { "class": `${prefixCls.value}-slot-select-arrow` }, [createTextVNode("▼")])])] });
7471
+ break;
7472
+ }
7473
+ case "tag":
7474
+ node = createVNode("span", { "class": `${prefixCls.value}-slot-tag` }, [config.props?.label ?? config.props?.value ?? ""]);
7475
+ break;
7476
+ case "custom":
7477
+ node = config.customRender?.(slotValue, (nextValue) => {
7478
+ updateSlot(config.key, nextValue);
7479
+ }, {
7480
+ disabled: senderCtx.value.disabled,
7481
+ readOnly: senderCtx.value.readOnly
7482
+ }, config);
7483
+ break;
7484
+ case "content":
7485
+ slotDom.innerText = stringifyValue(slotValue);
7486
+ slotDom.dataset.placeholder = config.props?.placeholder ?? "";
7487
+ return;
7488
+ default: return;
7489
+ }
7490
+ if (!node) return;
7491
+ mountedDomSet.value.add(slotDom);
7492
+ render(node, slotDom);
7493
+ };
7494
+ const buildSlotNodes = (configs) => {
7495
+ const list = [];
7496
+ configs.forEach((config) => {
7497
+ if (config.type === "text") {
7498
+ list.push(document.createTextNode(config.value || ""));
7499
+ return;
7500
+ }
7501
+ if (!("key" in config) || !config.key) {
7502
+ warning(false, "Sender", "Slot key is missing");
7503
+ return;
7504
+ }
7505
+ slotConfigMap.value.set(config.key, config);
7506
+ if (config.type === "content") {
7507
+ const before = buildSpaceSpan(config.key, "before");
7508
+ const slot = buildEditSlotSpan(config);
7509
+ const after = buildSpaceSpan(config.key, "after");
7510
+ slotValues.value[config.key] = slotValues.value[config.key] ?? getDefaultSlotValue(config);
7511
+ slot.innerText = stringifyValue(slotValues.value[config.key]);
7512
+ slot.dataset.placeholder = config.props?.placeholder ?? "";
7513
+ slotDomMap.value.set(`${config.key}_before`, before);
7514
+ slotDomMap.value.set(config.key, slot);
7515
+ slotDomMap.value.set(`${config.key}_after`, after);
7516
+ list.push(before, slot, after);
7517
+ return;
7518
+ }
7519
+ const slot = buildSlotSpan(config.key);
7520
+ slotValues.value[config.key] = slotValues.value[config.key] ?? getDefaultSlotValue(config);
7521
+ slotDomMap.value.set(config.key, slot);
7522
+ renderSlot(config, slot);
7523
+ list.push(slot);
7524
+ });
7525
+ return list;
7526
+ };
7527
+ const mergeSlotConfig = (configs) => {
7528
+ const nextValues = { ...slotValues.value };
7529
+ configs.forEach((config) => {
7530
+ if ("key" in config && config.key) {
7531
+ slotConfigMap.value.set(config.key, config);
7532
+ if (!(config.key in nextValues)) nextValues[config.key] = getDefaultSlotValue(config);
7533
+ }
7534
+ });
7535
+ slotValues.value = nextValues;
7536
+ };
7537
+ const clearEditor = () => {
7538
+ unmountAllPortals();
7539
+ slotDomMap.value.clear();
7540
+ slotConfigMap.value.clear();
7541
+ slotValues.value = {};
7542
+ currentSkillRef.value = void 0;
7543
+ if (skillDomRef.value) unmountDom(skillDomRef.value);
7544
+ skillDomRef.value = null;
7545
+ if (editableRef.value) editableRef.value.innerHTML = "";
7546
+ };
7547
+ const getSelection = () => {
7548
+ if (typeof window === "undefined") return null;
7549
+ return window.getSelection();
7550
+ };
7551
+ const setRange = (range, selection) => {
7552
+ selection.removeAllRanges();
7553
+ selection.addRange(range);
7554
+ };
7555
+ const setCursorPosition = (targetNode, offset, preventScroll) => {
7556
+ const editable = editableRef.value;
7557
+ if (!editable) return;
7558
+ editable.focus({ preventScroll });
7559
+ const selection = getSelection();
7560
+ if (!selection) return;
7561
+ const range = document.createRange();
7562
+ range.setStart(targetNode, offset);
7563
+ range.collapse(true);
7564
+ setRange(range, selection);
7565
+ };
7566
+ const setStartCursor = (preventScroll) => {
7567
+ const editable = editableRef.value;
7568
+ if (!editable) return;
7569
+ setCursorPosition(editable, skillDomRef.value ? 1 : 0, preventScroll);
7570
+ };
7571
+ const setEndCursor = (preventScroll) => {
7572
+ const editable = editableRef.value;
7573
+ if (!editable) return;
7574
+ editable.focus({ preventScroll });
7575
+ const selection = getSelection();
7576
+ if (!selection) return;
7577
+ const range = document.createRange();
7578
+ range.selectNodeContents(editable);
7579
+ range.collapse(false);
7580
+ setRange(range, selection);
7581
+ };
7582
+ const selectAll = (preventScroll) => {
7583
+ const editable = editableRef.value;
7584
+ if (!editable) return;
7585
+ editable.focus({ preventScroll });
7586
+ const selection = getSelection();
7587
+ if (!selection) return;
7588
+ const range = document.createRange();
7589
+ range.selectNodeContents(editable);
7590
+ if (skillDomRef.value) range.setStart(editable, 1);
7591
+ setRange(range, selection);
7592
+ };
7593
+ const focusSlot = (key, preventScroll) => {
7594
+ const editable = editableRef.value;
7595
+ if (!editable) return;
7596
+ const resolveTarget = (slotKey) => {
7597
+ const slotDom = slotDomMap.value.get(slotKey);
7598
+ const slotCfg = slotConfigMap.value.get(slotKey);
7599
+ if (!slotDom || !slotCfg) return null;
7600
+ if (slotCfg.type === "input") return slotDom.querySelector("input");
7601
+ if (slotCfg.type === "content") return slotDom;
7602
+ return null;
7603
+ };
7604
+ if (key) {
7605
+ const target = resolveTarget(key);
7606
+ if (target instanceof HTMLInputElement) {
7607
+ target.focus({ preventScroll });
7608
+ return;
7609
+ }
7610
+ if (target instanceof HTMLSpanElement) {
7611
+ setCursorPosition(target, 0, preventScroll);
7612
+ return;
7613
+ }
7614
+ }
7615
+ for (const node of Array.from(editable.childNodes)) {
7616
+ if (!(node instanceof HTMLElement)) continue;
7617
+ const slotKey = node.dataset.slotKey;
7618
+ const nodeType = node.dataset.nodeType;
7619
+ if (!slotKey || nodeType === "nbsp") continue;
7620
+ const target = resolveTarget(slotKey);
7621
+ if (target instanceof HTMLInputElement) {
7622
+ target.focus({ preventScroll });
7623
+ return;
7624
+ }
7625
+ if (target instanceof HTMLSpanElement) {
7626
+ setCursorPosition(target, 0, preventScroll);
7627
+ return;
7628
+ }
7629
+ }
7630
+ setEndCursor(preventScroll);
7631
+ };
7632
+ const removeSlot = (key, event) => {
7633
+ const editable = editableRef.value;
7634
+ if (!editable) return;
7635
+ editable.querySelectorAll(`[data-slot-key="${key}"]`).forEach((element) => {
7636
+ unmountDom(element);
7637
+ element.remove();
7638
+ });
7639
+ const nextValues = { ...slotValues.value };
7640
+ delete nextValues[key];
7641
+ slotValues.value = nextValues;
7642
+ slotConfigMap.value.delete(key);
7643
+ slotDomMap.value.delete(key);
7644
+ slotDomMap.value.delete(`${key}_before`);
7645
+ slotDomMap.value.delete(`${key}_after`);
7646
+ triggerValueChange(event);
7647
+ };
7648
+ const removeSkill = (triggerChange = true) => {
7649
+ const skillDom = skillDomRef.value;
7650
+ if (!skillDom) return;
7651
+ unmountDom(skillDom);
7652
+ skillDom.remove();
7653
+ skillDomRef.value = null;
7654
+ currentSkillRef.value = void 0;
7655
+ if (triggerChange) triggerValueChange();
7656
+ };
7657
+ const renderSkill = () => {
7658
+ const editable = editableRef.value;
7659
+ const skill = senderCtx.value.skill;
7660
+ if (!editable) return;
7661
+ if (!skill) {
7662
+ removeSkill(false);
7663
+ return;
7664
+ }
7665
+ let skillDom = skillDomRef.value;
7666
+ if (!skillDom) {
7667
+ skillDom = buildSkillSpan(skill.value);
7668
+ editable.insertBefore(skillDom, editable.firstChild);
7669
+ skillDomRef.value = skillDom;
7670
+ }
7671
+ currentSkillRef.value = skill;
7672
+ mountedDomSet.value.add(skillDom);
7673
+ render(createVNode(Skill_default, {
7674
+ "prefixCls": prefixCls.value,
7675
+ "skill": skill,
7676
+ "removeSkill": () => removeSkill(true)
7677
+ }, null), skillDom);
7678
+ };
7679
+ const updateSkillEmptyStatus = (value = getEditorValue()) => {
7680
+ const skillDom = skillDomRef.value;
7681
+ if (!skillDom) return;
7682
+ if (!value.value && value.slotConfig.length === 0 && !!senderCtx.value.placeholder) {
7683
+ skillDom.setAttribute("contenteditable", "true");
7684
+ skillDom.classList.add(`${prefixCls.value}-skill-empty`);
7685
+ } else {
7686
+ skillDom.setAttribute("contenteditable", "false");
7687
+ skillDom.classList.remove(`${prefixCls.value}-skill-empty`);
7688
+ }
7689
+ };
7690
+ const initFromSlotConfig = (configs) => {
7691
+ const editable = editableRef.value;
7692
+ if (!editable) return;
7693
+ clearEditor();
7694
+ const mergeConfigs = configs ?? [];
7695
+ mergeConfigs.forEach((config) => {
7696
+ if ("key" in config && config.key) {
7697
+ slotConfigMap.value.set(config.key, config);
7698
+ const defaultValue = getDefaultSlotValue(config);
7699
+ if (defaultValue !== void 0) slotValues.value[config.key] = defaultValue;
7700
+ }
7701
+ });
7702
+ buildSlotNodes(mergeConfigs).forEach((node) => {
7703
+ editable.appendChild(node);
7704
+ });
7705
+ renderSkill();
7706
+ nextTick(() => {
7707
+ triggerValueChange();
7708
+ });
7709
+ };
7710
+ const removeSpecificBRs = () => {
7711
+ if (senderCtx.value.submitType !== "enter") return;
7712
+ editableRef.value?.querySelectorAll("br").forEach((br) => br.remove());
7713
+ };
7714
+ const shouldSubmit = (event) => {
7715
+ const { key, shiftKey, ctrlKey, altKey, metaKey } = event;
7716
+ if (key !== "Enter") return false;
7717
+ const isModifierPressed = ctrlKey || altKey || metaKey;
7718
+ const submitType = senderCtx.value.submitType ?? "enter";
7719
+ return submitType === "enter" && !shiftKey && !isModifierPressed || submitType === "shiftEnter" && shiftKey && !isModifierPressed;
7720
+ };
7721
+ const findOuterContainer = (node) => {
7722
+ const editable = editableRef.value;
7723
+ if (!node || !editable) return null;
7724
+ let current = node;
7725
+ if (current.nodeType === Node.TEXT_NODE) current = current.parentNode;
7726
+ while (current && current !== editable) {
7727
+ if (current instanceof HTMLElement && current.tagName === "SPAN") return current;
7728
+ current = current.parentNode;
7729
+ }
7730
+ return null;
7731
+ };
7732
+ const handleBackspaceDelete = (event) => {
7733
+ const selection = getSelection();
7734
+ if (!selection || !selection.isCollapsed) return false;
7735
+ const editable = editableRef.value;
7736
+ if (!editable) return false;
7737
+ let anchorNode = selection.anchorNode;
7738
+ let offset = selection.anchorOffset;
7739
+ if (!anchorNode || !editable.contains(anchorNode)) return false;
7740
+ if (anchorNode === editable && offset > 0) {
7741
+ anchorNode = editable.childNodes[offset - 1] ?? anchorNode;
7742
+ offset = 0;
7743
+ }
7744
+ if (anchorNode.nodeType === Node.TEXT_NODE && offset > 0) return false;
7745
+ const target = anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentNode : anchorNode;
7746
+ const previous = target === editable ? editable.childNodes[Math.max(0, selection.anchorOffset - 1)] : target?.previousSibling;
7747
+ if (!(previous instanceof HTMLElement)) return false;
7748
+ const info = getNodeInfo(previous);
7749
+ if (info?.slotKey) {
7750
+ event.preventDefault();
7751
+ removeSlot(info.slotKey, event);
7752
+ return true;
7753
+ }
7754
+ if (info?.skillKey) {
7755
+ event.preventDefault();
7756
+ removeSkill(true);
7757
+ return true;
7758
+ }
7759
+ return false;
7760
+ };
7761
+ const onInternalKeyDown = (event) => {
7762
+ if (senderCtx.value.onKeyDown?.(event) === false || keyLock.value || isComposing.value) return;
7763
+ if (event.key === "Backspace" && handleBackspaceDelete(event)) return;
7764
+ if (shouldSubmit(event)) {
7765
+ event.preventDefault();
7766
+ keyLock.value = true;
7767
+ senderCtx.value.triggerSend?.();
7768
+ return;
7769
+ }
7770
+ if ((event.key === "a" || event.key === "A") && (event.ctrlKey || event.metaKey)) {
7771
+ event.preventDefault();
7772
+ selectAll(true);
7773
+ }
7774
+ };
7775
+ const onInternalKeyUp = (event) => {
7776
+ if (event.key === "Enter") keyLock.value = false;
7777
+ senderCtx.value.onKeyUp?.(event);
7778
+ };
7779
+ const onInternalInput = (event) => {
7780
+ removeSpecificBRs();
7781
+ triggerValueChange(event);
7782
+ };
7783
+ const onInternalPaste = (event) => {
7784
+ event.preventDefault();
7785
+ const files = event.clipboardData?.files;
7786
+ const text = event.clipboardData?.getData("text/plain") ?? "";
7787
+ if (!text && files?.length && senderCtx.value.onPasteFile) {
7788
+ senderCtx.value.onPasteFile(files);
7789
+ return;
7790
+ }
7791
+ if (text) {
7792
+ const selection = getSelection();
7793
+ if (selection && selection.rangeCount > 0) {
7794
+ const range = selection.getRangeAt(0);
7795
+ range.deleteContents();
7796
+ const textNode = document.createTextNode(text.replace(/\u200B/g, ""));
7797
+ range.insertNode(textNode);
7798
+ range.setStartAfter(textNode);
7799
+ range.collapse(true);
7800
+ selection.removeAllRanges();
7801
+ selection.addRange(range);
7802
+ }
7803
+ }
7804
+ onInternalInput(event);
7805
+ senderCtx.value.onPaste?.(event);
7806
+ };
7807
+ const onInternalSelect = () => {
7808
+ const selection = getSelection();
7809
+ const editable = editableRef.value;
7810
+ if (!selection || !editable) return;
7811
+ if (selection.focusNode === editable && selection.focusOffset === 0 && getEditorValue().skill) setCursorPosition(editable, 1);
7812
+ };
7813
+ const getRangeForInsert = (position = "cursor") => {
7814
+ const editable = editableRef.value;
7815
+ if (!editable) return null;
7816
+ const selection = getSelection();
7817
+ const range = document.createRange();
7818
+ if (position === "start") {
7819
+ const index = skillDomRef.value ? 1 : 0;
7820
+ range.setStart(editable, index);
7821
+ range.collapse(true);
7822
+ return {
7823
+ range,
7824
+ selection
7825
+ };
7826
+ }
7827
+ if (position === "end") {
7828
+ range.selectNodeContents(editable);
7829
+ range.collapse(false);
7830
+ return {
7831
+ range,
7832
+ selection
7833
+ };
7834
+ }
7835
+ if (selection && selection.rangeCount > 0 && editable.contains(selection.getRangeAt(0).startContainer)) {
7836
+ const currentRange = selection.getRangeAt(0).cloneRange();
7837
+ const outer = findOuterContainer(currentRange.startContainer);
7838
+ const outerInfo = outer ? getNodeInfo(outer) : null;
7839
+ if (outer && outerInfo?.slotKey && outerInfo.slotConfig?.type !== "content") {
7840
+ currentRange.setStartAfter(outer);
7841
+ currentRange.collapse(true);
7842
+ }
7843
+ return {
7844
+ range: currentRange,
7845
+ selection
7846
+ };
7847
+ }
7848
+ range.selectNodeContents(editable);
7849
+ range.collapse(false);
7850
+ return {
7851
+ range,
7852
+ selection
7853
+ };
7854
+ };
7855
+ const insert = (slotConfig, position = "cursor", replaceCharacters, preventScroll) => {
7856
+ const editable = editableRef.value;
7857
+ if (!editable || !slotConfig.length) return;
7858
+ mergeSlotConfig(slotConfig);
7859
+ const nodes = buildSlotNodes(slotConfig);
7860
+ if (!nodes.length) return;
7861
+ const insertContext = getRangeForInsert(position);
7862
+ if (!insertContext?.range) return;
7863
+ const { range, selection } = insertContext;
7864
+ editable.focus({ preventScroll });
7865
+ if (replaceCharacters) {
7866
+ if ((getSelection()?.toString() ?? "").endsWith(replaceCharacters)) range.setStart(range.startContainer, Math.max(0, range.startOffset - replaceCharacters.length));
7867
+ }
7868
+ range.deleteContents();
7869
+ nodes.forEach((node) => {
7870
+ range.insertNode(node);
7871
+ range.setStartAfter(node);
7872
+ });
7873
+ range.collapse(true);
7874
+ if (selection) {
7875
+ selection.removeAllRanges();
7876
+ selection.addRange(range);
7877
+ }
7878
+ onInternalInput();
7879
+ };
7880
+ const focus = (options) => {
7881
+ const cursor = options?.cursor ?? "end";
7882
+ if (cursor === "start") {
7883
+ setStartCursor(options?.preventScroll);
7884
+ return;
7885
+ }
7886
+ if (cursor === "all") {
7887
+ selectAll(options?.preventScroll);
7888
+ return;
7889
+ }
7890
+ if (cursor === "slot") {
7891
+ focusSlot(options?.key, options?.preventScroll);
7892
+ return;
7893
+ }
7894
+ setEndCursor(options?.preventScroll);
7895
+ };
7896
+ const clear = () => {
7897
+ clearEditor();
7898
+ renderSkill();
7899
+ onInternalInput();
7900
+ };
7901
+ expose({
7902
+ get nativeElement() {
7903
+ return editableRef.value ?? null;
7904
+ },
7905
+ focus,
7906
+ blur() {
7907
+ editableRef.value?.blur();
7908
+ },
7909
+ insert,
7910
+ clear,
7911
+ getValue: getEditorValue
7912
+ });
7913
+ const applySlotConfig = (configs, force = false) => {
7914
+ if (!force && configs === lastSlotConfigRef.value) return;
7915
+ lastSlotConfigRef.value = configs;
7916
+ initFromSlotConfig(configs);
7917
+ };
7918
+ watch(() => editableRef.value, (editable) => {
7919
+ if (!editable) return;
7920
+ applySlotConfig(senderCtx.value.slotConfig, true);
7921
+ }, { immediate: true });
7922
+ watch(() => senderCtx.value.slotConfig, (configs) => {
7923
+ applySlotConfig(configs);
7924
+ }, { immediate: true });
7925
+ watch(() => senderCtx.value.skill, (skill) => {
7926
+ if (skill === lastSkillRef.value && skillDomRef.value) return;
7927
+ lastSkillRef.value = skill;
7928
+ renderSkill();
7929
+ nextTick(() => {
7930
+ triggerValueChange();
7931
+ });
7932
+ }, { immediate: true });
7933
+ watch(() => senderCtx.value.readOnly, (readOnly) => {
7934
+ slotConfigMap.value.forEach((config, key) => {
7935
+ if (config.type === "content") slotDomMap.value.get(key)?.setAttribute("contenteditable", readOnly ? "false" : "true");
7936
+ });
7937
+ });
7938
+ onBeforeUnmount(() => {
7939
+ unmountAllPortals();
7940
+ });
7941
+ return () => {
7942
+ const inputCls = `${prefixCls.value}-input`;
7943
+ return createVNode("div", {
7944
+ "ref": editableRef,
7945
+ "role": "textbox",
7946
+ "tabindex": 0,
7947
+ "class": classNames([
7948
+ inputCls,
7949
+ `${inputCls}-slot`,
7950
+ senderCtx.value.classNames?.input
7951
+ ]),
7952
+ "style": mergeInputStyle.value,
7953
+ "data-placeholder": senderCtx.value.placeholder,
7954
+ "contenteditable": !senderCtx.value.readOnly,
7955
+ "spellcheck": false,
7956
+ "onInput": onInternalInput,
7957
+ "onKeydown": onInternalKeyDown,
7958
+ "onKeyup": onInternalKeyUp,
7959
+ "onPaste": onInternalPaste,
7960
+ "onCut": onInternalInput,
7961
+ "onSelect": onInternalSelect,
7962
+ "onFocus": (e) => {
7963
+ senderCtx.value.onFocus?.(e);
7964
+ },
7965
+ "onBlur": (e) => {
7966
+ keyLock.value = false;
7967
+ senderCtx.value.onBlur?.(e);
7968
+ },
7969
+ "onCompositionstart": () => {
7970
+ isComposing.value = true;
7971
+ },
7972
+ "onCompositionend": () => {
7973
+ isComposing.value = false;
7974
+ keyLock.value = false;
7975
+ }
7976
+ }, null);
7977
+ };
7978
+ }
7979
+ });
7980
+ //#endregion
7180
7981
  //#region components/sender/components/SpeechButton/RecordingIcon.tsx
7181
7982
  var SIZE = 1e3;
7182
7983
  var COUNT = 4;
@@ -7253,15 +8054,6 @@ var SpeechButton_default = /* @__PURE__ */ defineComponent({
7253
8054
  }
7254
8055
  });
7255
8056
  //#endregion
7256
- //#region components/sender/context.ts
7257
- var SenderContextKey = Symbol("sender-context");
7258
- function useSenderContext() {
7259
- return inject(SenderContextKey, computed(() => ({})));
7260
- }
7261
- function provideSenderContext(value) {
7262
- provide(SenderContextKey, value);
7263
- }
7264
- //#endregion
7265
8057
  //#region components/sender/components/TextArea.tsx
7266
8058
  var TextArea_default = /* @__PURE__ */ defineComponent({
7267
8059
  name: "SenderTextArea",
@@ -7472,6 +8264,191 @@ var genSenderHeaderStyle = (token) => {
7472
8264
  } };
7473
8265
  };
7474
8266
  //#endregion
8267
+ //#region components/sender/style/slot-textarea.ts
8268
+ var genSlotTextAreaStyle = (token) => {
8269
+ const { componentCls, antCls, calc } = token;
8270
+ const slotCls = `${componentCls}-slot`;
8271
+ const antInputCls = `${antCls}-input`;
8272
+ const antDropdownCls = `${antCls}-dropdown-trigger`;
8273
+ const slotInputCls = `${componentCls}-slot-input`;
8274
+ const slotSelectCls = `${componentCls}-slot-select`;
8275
+ const slotTagCls = `${componentCls}-slot-tag`;
8276
+ const slotContentCls = `${componentCls}-slot-content`;
8277
+ const skillCls = `${componentCls}-skill`;
8278
+ return { [componentCls]: {
8279
+ [`${componentCls}-input-slot`]: {
8280
+ outline: "none",
8281
+ cursor: "text",
8282
+ whiteSpace: "pre-wrap",
8283
+ width: "100%",
8284
+ caretColor: token.colorPrimary,
8285
+ fontSize: token.fontSize,
8286
+ lineHeight: token.lineHeight,
8287
+ [`&:empty::before`]: {
8288
+ content: "attr(data-placeholder)",
8289
+ color: token.colorTextPlaceholder
8290
+ }
8291
+ },
8292
+ [`${slotCls}:not(${slotContentCls})`]: {
8293
+ display: "inline-block",
8294
+ verticalAlign: "middle",
8295
+ alignItems: "center",
8296
+ marginBlock: 1,
8297
+ height: calc(token.fontSize).mul(token.lineHeight).add(2).equal(),
8298
+ wordBreak: "break-all",
8299
+ marginInline: token.marginXXS
8300
+ },
8301
+ [`${antInputCls}${slotInputCls}`]: {
8302
+ height: "100%",
8303
+ background: token.colorBgSlot,
8304
+ outline: "none",
8305
+ color: token.colorTextSlot,
8306
+ borderRadius: token.borderRadius,
8307
+ paddingInline: token.paddingXXS,
8308
+ fontSize: "inherit",
8309
+ lineHeight: "inherit",
8310
+ position: "relative",
8311
+ [`&::placeholder`]: {
8312
+ color: token.colorTextSlotPlaceholder,
8313
+ fontSize: "inherit",
8314
+ lineHeight: "inherit"
8315
+ }
8316
+ },
8317
+ [slotSelectCls]: {
8318
+ fontSize: token.fontSize,
8319
+ lineHeight: token.lineHeight,
8320
+ paddingInline: token.paddingXXS,
8321
+ transition: `border-color ${token.motionDurationMid}`,
8322
+ position: "relative",
8323
+ display: "inline-flex",
8324
+ alignItems: "center",
8325
+ cursor: "pointer",
8326
+ background: token.colorBgSlot,
8327
+ height: "100%",
8328
+ boxSizing: "border-box",
8329
+ borderRadius: token.borderRadius,
8330
+ color: token.colorTextSlot,
8331
+ border: `1px solid ${token.colorBorderSlot}`,
8332
+ [`&.placeholder`]: { color: token.colorTextSlotPlaceholder },
8333
+ [`&${antDropdownCls}-open`]: { borderColor: token.colorBorderSlotHover }
8334
+ },
8335
+ [`${slotSelectCls}-value`]: {
8336
+ flex: 1,
8337
+ fontSize: token.fontSize,
8338
+ lineHeight: token.lineHeight,
8339
+ [`&:empty::before`]: { content: "attr(data-placeholder)" }
8340
+ },
8341
+ [`${slotSelectCls}-arrow`]: {
8342
+ marginInlineStart: token.marginXXS,
8343
+ fontSize: token.fontSize,
8344
+ lineHeight: token.lineHeight,
8345
+ display: "inline-flex",
8346
+ alignItems: "center",
8347
+ justifyContent: "center"
8348
+ },
8349
+ [slotTagCls]: {
8350
+ background: token.colorBgSlot,
8351
+ border: `1px solid ${token.colorBorderSlot}`,
8352
+ outline: "none",
8353
+ color: token.colorTextSlot,
8354
+ borderRadius: token.borderRadius,
8355
+ padding: `0 ${unit(token.paddingXXS)}`,
8356
+ fontSize: token.fontSize,
8357
+ lineHeight: token.lineHeight,
8358
+ height: "100%",
8359
+ boxSizing: "border-box",
8360
+ position: "relative",
8361
+ cursor: "default"
8362
+ },
8363
+ [slotContentCls]: {
8364
+ height: calc(token.fontSize).mul(token.lineHeight).add(2).equal(),
8365
+ caretColor: token.colorPrimary,
8366
+ background: token.colorBgSlot,
8367
+ outline: "none",
8368
+ color: token.colorTextSlot,
8369
+ borderRadius: token.borderRadius,
8370
+ paddingInline: token.paddingXXS,
8371
+ boxSizing: "border-box",
8372
+ verticalAlign: "middle",
8373
+ fontSize: token.fontSize,
8374
+ marginBlock: 1,
8375
+ lineHeight: token.lineHeight,
8376
+ display: "inline-block",
8377
+ position: "relative",
8378
+ cursor: "text",
8379
+ [`&:empty`]: {
8380
+ width: "fit-content",
8381
+ [`&::after`]: {
8382
+ display: "inline-block",
8383
+ height: "inherit",
8384
+ content: "attr(data-placeholder)",
8385
+ color: token.colorTextSlotPlaceholder
8386
+ }
8387
+ }
8388
+ },
8389
+ [`${slotCls}-no-width`]: {
8390
+ userSelect: "none",
8391
+ width: "3px",
8392
+ display: "inline-block",
8393
+ lineHeight: "inherit"
8394
+ },
8395
+ [skillCls]: {
8396
+ display: "inline-block",
8397
+ verticalAlign: "baseline",
8398
+ alignItems: "center",
8399
+ marginBlock: 1,
8400
+ height: calc(token.fontSize).mul(token.lineHeight).add(2).equal(),
8401
+ wordBreak: "break-all",
8402
+ paddingInlineEnd: 0,
8403
+ paddingInlineStart: 0,
8404
+ marginInlineEnd: 0,
8405
+ marginInlineStart: -1,
8406
+ [`&${skillCls}-empty`]: { [`&::after`]: {
8407
+ display: "inline-block",
8408
+ pointerEvents: "none",
8409
+ height: "inherit",
8410
+ content: "attr(data-placeholder)",
8411
+ color: token.colorTextPlaceholder
8412
+ } }
8413
+ },
8414
+ [`${skillCls}-wrapper`]: {
8415
+ height: "100%",
8416
+ display: "inline-flex"
8417
+ },
8418
+ [`${skillCls}-tag`]: {
8419
+ paddingInline: token.paddingXS,
8420
+ height: "100%",
8421
+ backgroundColor: token.colorBgSkill,
8422
+ borderRadius: token.borderRadius,
8423
+ color: token.colorPrimary,
8424
+ alignItems: "center",
8425
+ fontWeight: 500,
8426
+ display: "inline-flex",
8427
+ cursor: "pointer",
8428
+ gap: token.marginXXS,
8429
+ transition: `background-color ${token.motionDurationMid}`,
8430
+ [`&:hover`]: {
8431
+ backgroundColor: token.colorBgSkillHover,
8432
+ [`${skillCls}-close:not(${skillCls}-close-disabled)`]: { color: token.colorPrimaryHover }
8433
+ }
8434
+ },
8435
+ [`${skillCls}-close`]: {
8436
+ fontSize: token.fontSizeSM,
8437
+ display: "inline-flex",
8438
+ transition: `color ${token.motionDurationMid}`,
8439
+ color: token.colorPrimary
8440
+ },
8441
+ [`${skillCls}-close-disabled`]: {
8442
+ cursor: "not-allowed",
8443
+ color: token.colorTextDisabled
8444
+ },
8445
+ [`${skillCls}-holder`]: {
8446
+ width: token.marginXS,
8447
+ height: "100%"
8448
+ }
8449
+ } };
8450
+ };
8451
+ //#endregion
7475
8452
  //#region components/sender/style/switch.ts
7476
8453
  var genSenderSwitchStyle = (token) => {
7477
8454
  const { componentCls, antCls } = token;
@@ -7579,12 +8556,26 @@ var genSenderStyle = (token) => {
7579
8556
  };
7580
8557
  var prepareComponentToken$5 = (token) => {
7581
8558
  const { colorPrimary, colorFillTertiary } = token;
8559
+ const colorBgSlot = new FastColor(colorPrimary).setA(.06).toRgbString();
8560
+ const colorBgSkill = new FastColor(colorPrimary).setA(.08).toRgbString();
8561
+ const colorBgSkillHover = new FastColor(colorPrimary).setA(.15).toRgbString();
8562
+ const colorTextSlot = colorPrimary;
8563
+ const colorTextSlotPlaceholder = new FastColor(colorPrimary).setA(.25).toRgbString();
8564
+ const colorBorderSlotHover = new FastColor(colorPrimary).setA(.1).toRgbString();
8565
+ const colorBorderSlot = colorBgSlot;
7582
8566
  const colorBorderInput = new FastColor(colorFillTertiary).setA(.1).toRgbString();
7583
8567
  const switchCheckedBg = new FastColor(colorPrimary).setA(.08).toRgbString();
7584
8568
  const switchCheckedHoverBg = new FastColor(colorPrimary).setA(.1).toRgbString();
7585
8569
  const switchUncheckedHoverBg = new FastColor(colorFillTertiary).setA(.04).toRgbString();
7586
8570
  const colorBgActionsDisabled = new FastColor(colorPrimary).setA(.45).toRgbString();
7587
8571
  return {
8572
+ colorBgSlot,
8573
+ colorBgSkill,
8574
+ colorBgSkillHover,
8575
+ colorTextSlot,
8576
+ colorTextSlotPlaceholder,
8577
+ colorBorderSlotHover,
8578
+ colorBorderSlot,
7588
8579
  colorBorderInput,
7589
8580
  switchCheckedBg,
7590
8581
  switchCheckedHoverBg,
@@ -7599,7 +8590,8 @@ var style_default$5 = genStyleHooks("Sender", (token) => {
7599
8590
  return [
7600
8591
  genSenderStyle(senderToken),
7601
8592
  genSenderHeaderStyle(senderToken),
7602
- genSenderSwitchStyle(senderToken)
8593
+ genSenderSwitchStyle(senderToken),
8594
+ genSlotTextAreaStyle(senderToken)
7603
8595
  ];
7604
8596
  }, prepareComponentToken$5);
7605
8597
  //#endregion
@@ -7658,6 +8650,14 @@ var Sender_default = /* @__PURE__ */ defineComponent({
7658
8650
  type: Boolean,
7659
8651
  default: false
7660
8652
  },
8653
+ slotConfig: {
8654
+ type: Array,
8655
+ default: void 0
8656
+ },
8657
+ skill: {
8658
+ type: Object,
8659
+ default: void 0
8660
+ },
7661
8661
  placeholder: {
7662
8662
  type: String,
7663
8663
  default: void 0
@@ -7756,21 +8756,40 @@ var Sender_default = /* @__PURE__ */ defineComponent({
7756
8756
  const [hashId, cssVarCls] = style_default$5(prefixCls);
7757
8757
  const containerRef = ref();
7758
8758
  const inputRef = ref();
8759
+ const isSlotMode = computed(() => Array.isArray(props.slotConfig) || !!props.skill?.value);
7759
8760
  const innerValue = ref(props.defaultValue);
7760
8761
  const mergedValue = computed(() => props.value ?? innerValue.value);
7761
- const triggerValueChange = (nextValue, event) => {
8762
+ const triggerValueChange = (nextValue, event, slotConfig, skill) => {
7762
8763
  innerValue.value = nextValue;
7763
- props.onChange?.(nextValue, event);
8764
+ props.onChange?.(nextValue, event, slotConfig, skill);
7764
8765
  };
8766
+ const submitDisabled = ref(!mergedValue.value);
8767
+ watch(() => mergedValue.value, (next) => {
8768
+ if (!isSlotMode.value) submitDisabled.value = !next;
8769
+ }, { immediate: true });
7765
8770
  const [speechPermission, triggerSpeech, speechRecording] = useSpeech((transcript) => {
8771
+ if (isSlotMode.value) {
8772
+ inputRef.value?.insert?.([{
8773
+ type: "text",
8774
+ value: transcript
8775
+ }]);
8776
+ return;
8777
+ }
7766
8778
  triggerValueChange(`${mergedValue.value} ${transcript}`);
7767
8779
  }, () => props.allowSpeech);
7768
8780
  const triggerSend = () => {
7769
- if (props.onSubmit && !props.loading && mergedValue.value) props.onSubmit(mergedValue.value);
8781
+ if (!props.onSubmit || props.loading || submitDisabled.value) return;
8782
+ const value = inputRef.value?.getValue?.() ?? { value: "" };
8783
+ const slotConfig = "slotConfig" in value ? value.slotConfig : void 0;
8784
+ const skill = "skill" in value ? value.skill : void 0;
8785
+ props.onSubmit(value.value, slotConfig, skill);
7770
8786
  };
7771
8787
  const triggerClear = () => {
8788
+ if (inputRef.value?.clear) {
8789
+ inputRef.value.clear();
8790
+ return;
8791
+ }
7772
8792
  triggerValueChange("");
7773
- inputRef.value?.clear();
7774
8793
  };
7775
8794
  expose({
7776
8795
  get nativeElement() {
@@ -7786,7 +8805,19 @@ var Sender_default = /* @__PURE__ */ defineComponent({
7786
8805
  triggerClear();
7787
8806
  },
7788
8807
  insert(text, position) {
7789
- inputRef.value?.insert(text, position);
8808
+ if (isSlotMode.value) {
8809
+ const slotList = Array.isArray(text) ? text : [{
8810
+ type: "text",
8811
+ value: text
8812
+ }];
8813
+ inputRef.value?.insert?.(slotList, position);
8814
+ return;
8815
+ }
8816
+ const textValue = Array.isArray(text) ? text.map((config) => {
8817
+ if (config.type === "text") return config.value ?? "";
8818
+ return config.formatResult?.(config.props?.defaultValue) ?? "";
8819
+ }).join("") : text;
8820
+ inputRef.value?.insert?.(textValue, position);
7790
8821
  },
7791
8822
  getValue() {
7792
8823
  return inputRef.value?.getValue() ?? { value: "" };
@@ -7809,15 +8840,20 @@ var Sender_default = /* @__PURE__ */ defineComponent({
7809
8840
  triggerSend,
7810
8841
  placeholder: props.placeholder,
7811
8842
  onFocus: props.onFocus,
7812
- onBlur: props.onBlur
8843
+ onBlur: props.onBlur,
8844
+ slotConfig: props.slotConfig,
8845
+ skill: props.skill,
8846
+ setSubmitDisabled: (disabled) => {
8847
+ submitDisabled.value = disabled;
8848
+ }
7813
8849
  })));
7814
8850
  const actionBtnCls = computed(() => `${prefixCls.value}-actions-btn`);
7815
8851
  provideActionButtonContext(computed(() => ({
7816
8852
  prefixCls: actionBtnCls.value,
7817
8853
  onSend: triggerSend,
7818
- onSendDisabled: !mergedValue.value,
8854
+ onSendDisabled: submitDisabled.value,
7819
8855
  onClear: triggerClear,
7820
- onClearDisabled: !mergedValue.value,
8856
+ onClearDisabled: submitDisabled.value,
7821
8857
  onCancel: props.onCancel,
7822
8858
  onCancelDisabled: !props.loading,
7823
8859
  onSpeech: () => triggerSpeech(false),
@@ -7870,8 +8906,9 @@ var Sender_default = /* @__PURE__ */ defineComponent({
7870
8906
  "class": [`${cls}-content`, props.classNames.content],
7871
8907
  "style": props.styles.content,
7872
8908
  "onMousedown": (e) => {
7873
- if (e.target !== containerRef.value?.querySelector(`.${cls}-input`)) e.preventDefault();
7874
- inputRef.value?.focus();
8909
+ const inputNode = containerRef.value?.querySelector(`.${cls}-input`);
8910
+ if (!isSlotMode.value && e.target !== inputNode) e.preventDefault();
8911
+ if (e.target === inputNode || e.target === containerRef.value) inputRef.value?.focus();
7875
8912
  }
7876
8913
  }, [
7877
8914
  prefixNode && createVNode("div", {
@@ -7882,7 +8919,7 @@ var Sender_default = /* @__PURE__ */ defineComponent({
7882
8919
  ],
7883
8920
  "style": [contextConfig.value.styles?.prefix, props.styles.prefix]
7884
8921
  }, [prefixNode]),
7885
- createVNode(TextArea_default, { "ref": inputRef }, null),
8922
+ isSlotMode.value ? createVNode(SlotTextArea_default, { "ref": inputRef }, null) : createVNode(TextArea_default, { "ref": inputRef }, null),
7886
8923
  suffixNode && createVNode("div", {
7887
8924
  "class": [
7888
8925
  actionListCls,
@@ -8127,7 +9164,7 @@ var SenderSwitch_default = /* @__PURE__ */ defineComponent({
8127
9164
  "class": [`${cls}-content`, props.classNames.content],
8128
9165
  "style": props.styles.content
8129
9166
  }, {
8130
- classNames: {
9167
+ classes: {
8131
9168
  icon: props.classNames.icon,
8132
9169
  content: props.classNames.title
8133
9170
  },
@@ -8647,20 +9684,24 @@ function useActive(items, open, rtl, onCancel) {
8647
9684
  case "ArrowDown":
8648
9685
  offsetRow(1);
8649
9686
  event.preventDefault();
9687
+ event.stopPropagation();
8650
9688
  break;
8651
9689
  case "ArrowUp":
8652
9690
  offsetRow(-1);
8653
9691
  event.preventDefault();
9692
+ event.stopPropagation();
8654
9693
  break;
8655
9694
  case "ArrowRight":
8656
9695
  if (rtl.value) offsetPrev();
8657
9696
  else offsetNext();
8658
9697
  event.preventDefault();
9698
+ event.stopPropagation();
8659
9699
  break;
8660
9700
  case "ArrowLeft":
8661
9701
  if (rtl.value) offsetNext();
8662
9702
  else offsetPrev();
8663
9703
  event.preventDefault();
9704
+ event.stopPropagation();
8664
9705
  break;
8665
9706
  case "Enter":
8666
9707
  event.preventDefault();