@antdv-next/x 0.0.2 → 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.umd.js CHANGED
@@ -44,7 +44,7 @@
44
44
  antdv_next_dist_theme_useToken = __toESM(antdv_next_dist_theme_useToken);
45
45
  mermaid = __toESM(mermaid);
46
46
  //#region package.json
47
- var version = "0.0.2";
47
+ var version = "0.0.4";
48
48
  //#endregion
49
49
  //#region components/x-provider/context.ts
50
50
  var XProviderContextKey = Symbol("antdv-next-x-provider-context");
@@ -523,7 +523,7 @@
523
523
  }, prepareComponentToken$13);
524
524
  //#endregion
525
525
  //#region components/actions/Actions.tsx
526
- function _isSlot$6(s) {
526
+ function _isSlot$7(s) {
527
527
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
528
528
  }
529
529
  function getMotionTransitionProps(motionName) {
@@ -683,7 +683,7 @@
683
683
  attrs.style,
684
684
  props.style
685
685
  ]
686
- }), [transitionProps.value ? (0, vue.createVNode)(vue.Transition, transitionProps.value, _isSlot$6(_slot = renderList()) ? _slot : { default: () => [_slot] }) : renderList()]);
686
+ }), [transitionProps.value ? (0, vue.createVNode)(vue.Transition, transitionProps.value, _isSlot$7(_slot = renderList()) ? _slot : { default: () => [_slot] }) : renderList()]);
687
687
  };
688
688
  }
689
689
  });
@@ -2199,7 +2199,7 @@
2199
2199
  });
2200
2200
  //#endregion
2201
2201
  //#region components/file-card/List.tsx
2202
- function _isSlot$5(s) {
2202
+ function _isSlot$6(s) {
2203
2203
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
2204
2204
  }
2205
2205
  var XFileCardList = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -2367,7 +2367,7 @@
2367
2367
  "style": [props.style, splitStyles.value.root],
2368
2368
  "onScroll": checkPing
2369
2369
  }, [
2370
- (0, vue.createVNode)(vue.TransitionGroup, { "name": `${compCls.value}-motion` }, _isSlot$5(_slot = list.value.map((item, itemIndex) => {
2370
+ (0, vue.createVNode)(vue.TransitionGroup, { "name": `${compCls.value}-motion` }, _isSlot$6(_slot = list.value.map((item, itemIndex) => {
2371
2371
  const { __key, ...fileItem } = item;
2372
2372
  const cardSlots = {
2373
2373
  description: slots.description ? (slotInfo) => slots.description?.({
@@ -2694,7 +2694,7 @@
2694
2694
  });
2695
2695
  //#endregion
2696
2696
  //#region components/attachments/PlaceholderUploader.tsx
2697
- function _isSlot$4(s) {
2697
+ function _isSlot$5(s) {
2698
2698
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
2699
2699
  }
2700
2700
  var PlaceholderUploader = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -2789,7 +2789,7 @@
2789
2789
  border: 0,
2790
2790
  background: "transparent"
2791
2791
  }
2792
- }), _isSlot$4(node) ? node : { default: () => [node] })]);
2792
+ }), _isSlot$5(node) ? node : { default: () => [node] })]);
2793
2793
  };
2794
2794
  }
2795
2795
  });
@@ -2906,7 +2906,7 @@
2906
2906
  }, prepareComponentToken$11);
2907
2907
  //#endregion
2908
2908
  //#region components/attachments/index.tsx
2909
- function _isSlot$3(s) {
2909
+ function _isSlot$4(s) {
2910
2910
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
2911
2911
  }
2912
2912
  var XAttachments = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -3132,7 +3132,7 @@
3132
3132
  props.rootClass,
3133
3133
  mergedClasses.value.root
3134
3134
  ]
3135
- }, _isSlot$3(_slot = getPlaceholderNode("drop")) ? _slot : { default: () => [_slot] })]);
3135
+ }, _isSlot$4(_slot = getPlaceholderNode("drop")) ? _slot : { default: () => [_slot] })]);
3136
3136
  };
3137
3137
  const renderNormalMode = () => {
3138
3138
  let _slot2;
@@ -3171,7 +3171,7 @@
3171
3171
  "getDropContainer": props.getDropContainer || (() => containerRef.value),
3172
3172
  "prefixCls": props.prefixCls,
3173
3173
  "class": [hashId.value, cssVarCls.value]
3174
- }, _isSlot$3(_slot2 = getPlaceholderNode("drop")) ? _slot2 : { default: () => [_slot2] })
3174
+ }, _isSlot$4(_slot2 = getPlaceholderNode("drop")) ? _slot2 : { default: () => [_slot2] })
3175
3175
  ]);
3176
3176
  };
3177
3177
  return () => slots.default ? renderWithChildren() : renderNormalMode();
@@ -4191,7 +4191,7 @@
4191
4191
  });
4192
4192
  //#endregion
4193
4193
  //#region components/bubble/Divider.tsx
4194
- function _isSlot$2(s) {
4194
+ function _isSlot$3(s) {
4195
4195
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
4196
4196
  }
4197
4197
  var XBubbleDivider = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -4257,7 +4257,7 @@
4257
4257
  "class": [`${props.prefixCls}-divider`, props.class],
4258
4258
  "styles": props.styles,
4259
4259
  "classes": props.classes
4260
- }), { contentRender: ({ content }) => (0, vue.createVNode)(antdv_next.Divider, props.dividerProps, _isSlot$2(content) ? content : { default: () => [content] }) });
4260
+ }), { contentRender: ({ content }) => (0, vue.createVNode)(antdv_next.Divider, props.dividerProps, _isSlot$3(content) ? content : { default: () => [content] }) });
4261
4261
  }
4262
4262
  });
4263
4263
  //#endregion
@@ -5579,7 +5579,7 @@
5579
5579
  }
5580
5580
  //#endregion
5581
5581
  //#region components/conversations/Item.tsx
5582
- function _isSlot$1(s) {
5582
+ function _isSlot$2(s) {
5583
5583
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
5584
5584
  }
5585
5585
  var stopPropagation = (event) => {
@@ -5720,14 +5720,14 @@
5720
5720
  }
5721
5721
  }, [
5722
5722
  hasRenderableNode$6(iconNode) && (0, vue.createVNode)("div", { "class": `${props.prefixCls}-icon` }, [iconNode]),
5723
- (0, vue.createVNode)(antdv_next.Typography.Text, { "class": `${props.prefixCls}-label` }, _isSlot$1(labelNode) ? labelNode : { default: () => [labelNode] }),
5723
+ (0, vue.createVNode)(antdv_next.Typography.Text, { "class": `${props.prefixCls}-label` }, _isSlot$2(labelNode) ? labelNode : { default: () => [labelNode] }),
5724
5724
  !disabled && props.menu && (0, vue.createVNode)("div", { "onClick": stopPropagation }, [(0, vue.createVNode)(antdv_next.Dropdown, {
5725
5725
  "menu": menuProps.value,
5726
5726
  "placement": props.direction === "rtl" ? "bottomLeft" : "bottomRight",
5727
5727
  "trigger": ["click"],
5728
5728
  "disabled": disabled,
5729
5729
  "getPopupContainer": menuProps.value?.getPopupContainer
5730
- }, _isSlot$1(_slot = renderMenuTrigger(props.info)) ? _slot : { default: () => [_slot] })])
5730
+ }, _isSlot$2(_slot = renderMenuTrigger(props.info)) ? _slot : { default: () => [_slot] })])
5731
5731
  ]);
5732
5732
  };
5733
5733
  }
@@ -7074,10 +7074,6 @@
7074
7074
  variant: {
7075
7075
  type: String,
7076
7076
  default: void 0
7077
- },
7078
- class: {
7079
- type: String,
7080
- default: void 0
7081
7077
  }
7082
7078
  },
7083
7079
  setup(props, { attrs }) {
@@ -7100,7 +7096,7 @@
7100
7096
  "disabled": mergedDisabled.value,
7101
7097
  "class": [
7102
7098
  prefixCls,
7103
- props.class,
7099
+ attrs.class,
7104
7100
  { [`${prefixCls}-disabled`]: mergedDisabled.value }
7105
7101
  ],
7106
7102
  "onClick": (e) => {
@@ -7211,6 +7207,811 @@
7211
7207
  }
7212
7208
  });
7213
7209
  //#endregion
7210
+ //#region components/sender/context.ts
7211
+ var SenderContextKey = Symbol("sender-context");
7212
+ function useSenderContext() {
7213
+ return (0, vue.inject)(SenderContextKey, (0, vue.computed)(() => ({})));
7214
+ }
7215
+ function provideSenderContext(value) {
7216
+ (0, vue.provide)(SenderContextKey, value);
7217
+ }
7218
+ //#endregion
7219
+ //#region components/sender/components/Skill.tsx
7220
+ function _isSlot$1(s) {
7221
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !(0, vue.isVNode)(s);
7222
+ }
7223
+ var Skill_default = /* @__PURE__ */ (0, vue.defineComponent)({
7224
+ name: "SenderSkill",
7225
+ props: {
7226
+ prefixCls: {
7227
+ type: String,
7228
+ required: true
7229
+ },
7230
+ skill: {
7231
+ type: Object,
7232
+ required: true
7233
+ },
7234
+ removeSkill: {
7235
+ type: Function,
7236
+ required: true
7237
+ }
7238
+ },
7239
+ setup(props) {
7240
+ const componentCls = (0, vue.computed)(() => `${props.prefixCls}-skill`);
7241
+ const closeNode = (0, vue.computed)(() => {
7242
+ const closable = props.skill.closable;
7243
+ if (!closable) return null;
7244
+ const config = typeof closable === "boolean" ? {} : closable;
7245
+ const closeIcon = config.closeIcon ?? (0, vue.createVNode)(_antdv_next_icons.CloseOutlined, { "class": `${componentCls.value}-close-icon` }, null);
7246
+ return (0, vue.createVNode)("div", {
7247
+ "class": (0, _v_c_util.classNames)([`${componentCls.value}-close`, { [`${componentCls.value}-close-disabled`]: config.disabled }]),
7248
+ "role": "button",
7249
+ "aria-label": "Close skill",
7250
+ "tabindex": 0,
7251
+ "onClick": (event) => {
7252
+ if (config.disabled) return;
7253
+ event.stopPropagation();
7254
+ props.removeSkill();
7255
+ config.onClose?.(event);
7256
+ }
7257
+ }, [closeIcon]);
7258
+ });
7259
+ return () => {
7260
+ const mergeTitle = props.skill.title ?? props.skill.value;
7261
+ const titleNode = props.skill.toolTip ? (0, vue.createVNode)(antdv_next.Tooltip, props.skill.toolTip, _isSlot$1(mergeTitle) ? mergeTitle : { default: () => [mergeTitle] }) : mergeTitle;
7262
+ return (0, vue.createVNode)("div", {
7263
+ "class": `${componentCls.value}-wrapper`,
7264
+ "contenteditable": false
7265
+ }, [(0, vue.createVNode)("div", {
7266
+ "class": `${componentCls.value}-tag`,
7267
+ "contenteditable": false,
7268
+ "role": "button",
7269
+ "tabindex": 0
7270
+ }, [(0, vue.createVNode)("span", { "class": `${componentCls.value}-tag-text` }, [titleNode]), closeNode.value]), (0, vue.createVNode)("div", { "class": `${componentCls.value}-holder` }, null)]);
7271
+ };
7272
+ }
7273
+ });
7274
+ //#endregion
7275
+ //#region components/sender/components/SlotTextArea.tsx
7276
+ var SUPPORTED_INPUT_TYPES = new Set([
7277
+ "input",
7278
+ "select",
7279
+ "custom",
7280
+ "content"
7281
+ ]);
7282
+ function stringifyValue(value) {
7283
+ if (value === void 0 || value === null) return "";
7284
+ if (typeof value === "string") return value;
7285
+ if (typeof value === "number" || typeof value === "boolean") return `${value}`;
7286
+ try {
7287
+ return JSON.stringify(value);
7288
+ } catch {
7289
+ return "";
7290
+ }
7291
+ }
7292
+ function getDefaultSlotValue(config) {
7293
+ if (!config.key) return void 0;
7294
+ const props = config.props ?? {};
7295
+ if (SUPPORTED_INPUT_TYPES.has(config.type)) return props.defaultValue ?? "";
7296
+ return props.value ?? props.label ?? "";
7297
+ }
7298
+ var SlotTextArea_default = /* @__PURE__ */ (0, vue.defineComponent)({
7299
+ name: "SlotTextArea",
7300
+ setup(_, { expose }) {
7301
+ const senderCtx = useSenderContext();
7302
+ const editableRef = (0, vue.ref)();
7303
+ const slotDomMap = (0, vue.ref)(/* @__PURE__ */ new Map());
7304
+ const slotConfigMap = (0, vue.ref)(/* @__PURE__ */ new Map());
7305
+ const slotValues = (0, vue.ref)({});
7306
+ const mountedDomSet = (0, vue.ref)(/* @__PURE__ */ new Set());
7307
+ const skillDomRef = (0, vue.ref)(null);
7308
+ const currentSkillRef = (0, vue.ref)(void 0);
7309
+ const lastSlotConfigRef = (0, vue.ref)(void 0);
7310
+ const lastSkillRef = (0, vue.ref)(void 0);
7311
+ const isComposing = (0, vue.ref)(false);
7312
+ const keyLock = (0, vue.ref)(false);
7313
+ const prefixCls = (0, vue.computed)(() => senderCtx.value.prefixCls || "antd-sender");
7314
+ const mergeInputStyle = (0, vue.computed)(() => ({
7315
+ ...senderCtx.value.styles?.input,
7316
+ ...getAutoSizeStyle()
7317
+ }));
7318
+ const getAutoSizeStyle = () => {
7319
+ const autoSize = senderCtx.value.autoSize;
7320
+ if (autoSize === true) return { height: "auto" };
7321
+ if (!autoSize || typeof autoSize !== "object") return {};
7322
+ const lineHeight = 22;
7323
+ return {
7324
+ minHeight: autoSize.minRows ? `${autoSize.minRows * lineHeight}px` : void 0,
7325
+ maxHeight: autoSize.maxRows ? `${autoSize.maxRows * lineHeight}px` : void 0,
7326
+ overflowY: "auto"
7327
+ };
7328
+ };
7329
+ const getNodeInfo = (targetNode) => {
7330
+ if (!targetNode?.dataset) return null;
7331
+ const slotKey = targetNode.dataset.slotKey;
7332
+ return {
7333
+ slotKey,
7334
+ skillKey: targetNode.dataset.skillKey,
7335
+ nodeType: targetNode.dataset.nodeType,
7336
+ slotConfig: slotKey ? slotConfigMap.value.get(slotKey) : void 0
7337
+ };
7338
+ };
7339
+ const unmountDom = (container) => {
7340
+ if (!container) return;
7341
+ (0, vue.render)(null, container);
7342
+ mountedDomSet.value.delete(container);
7343
+ };
7344
+ const unmountAllPortals = () => {
7345
+ mountedDomSet.value.forEach((container) => {
7346
+ (0, vue.render)(null, container);
7347
+ });
7348
+ mountedDomSet.value.clear();
7349
+ };
7350
+ const buildSkillSpan = (key) => {
7351
+ const span = document.createElement("span");
7352
+ span.setAttribute("contenteditable", "false");
7353
+ span.dataset.skillKey = key;
7354
+ span.dataset.placeholder = senderCtx.value.placeholder || "";
7355
+ span.className = `${prefixCls.value}-skill`;
7356
+ return span;
7357
+ };
7358
+ const buildSlotSpan = (key) => {
7359
+ const span = document.createElement("span");
7360
+ span.setAttribute("contenteditable", "false");
7361
+ span.dataset.slotKey = key;
7362
+ span.className = `${prefixCls.value}-slot`;
7363
+ return span;
7364
+ };
7365
+ const buildEditSlotSpan = (config) => {
7366
+ const span = document.createElement("span");
7367
+ span.setAttribute("contenteditable", senderCtx.value.readOnly ? "false" : "true");
7368
+ span.dataset.slotKey = config.key;
7369
+ span.className = `${prefixCls.value}-slot ${prefixCls.value}-slot-content`;
7370
+ return span;
7371
+ };
7372
+ const buildSpaceSpan = (slotKey, position) => {
7373
+ const span = document.createElement("span");
7374
+ span.setAttribute("contenteditable", "false");
7375
+ span.dataset.slotKey = slotKey;
7376
+ span.dataset.nodeType = "nbsp";
7377
+ span.className = `${prefixCls.value}-slot-${position} ${prefixCls.value}-slot-no-width`;
7378
+ span.textContent = "\xA0";
7379
+ return span;
7380
+ };
7381
+ const getNodeTextValue = (node) => {
7382
+ if (node.nodeType === Node.TEXT_NODE) return node.textContent ?? "";
7383
+ if (node.nodeType !== Node.ELEMENT_NODE) return "";
7384
+ const element = node;
7385
+ const nodeInfo = getNodeInfo(element);
7386
+ if (!nodeInfo) return element.innerText || "";
7387
+ if (nodeInfo.skillKey) return "";
7388
+ if (nodeInfo.slotKey) {
7389
+ if (nodeInfo.nodeType === "nbsp") return " ";
7390
+ const config = nodeInfo.slotConfig;
7391
+ if (!config || config.type === "content") return element.innerText || "";
7392
+ const rawValue = slotValues.value[nodeInfo.slotKey];
7393
+ return config.formatResult?.(rawValue) ?? stringifyValue(rawValue);
7394
+ }
7395
+ return element.innerText || "";
7396
+ };
7397
+ const getEditorValue = () => {
7398
+ const editable = editableRef.value;
7399
+ const emptyResult = {
7400
+ value: "",
7401
+ slotConfig: [],
7402
+ skill: void 0
7403
+ };
7404
+ if (!editable) return emptyResult;
7405
+ const childNodes = editable.childNodes;
7406
+ if (childNodes.length === 0) return emptyResult;
7407
+ const textList = [];
7408
+ const currentSlotConfig = [];
7409
+ let currentSkill;
7410
+ childNodes.forEach((node) => {
7411
+ const textValue = getNodeTextValue(node);
7412
+ textList.push(textValue);
7413
+ if (node.nodeType === Node.TEXT_NODE) {
7414
+ if (textValue) currentSlotConfig.push({
7415
+ type: "text",
7416
+ value: textValue
7417
+ });
7418
+ return;
7419
+ }
7420
+ if (node.nodeType === Node.ELEMENT_NODE) {
7421
+ const info = getNodeInfo(node);
7422
+ if (!info) return;
7423
+ if (info.skillKey && currentSkillRef.value) currentSkill = currentSkillRef.value;
7424
+ if (info.slotKey && info.nodeType !== "nbsp") {
7425
+ const cfg = slotConfigMap.value.get(info.slotKey);
7426
+ if (cfg) currentSlotConfig.push({
7427
+ ...cfg,
7428
+ value: textValue
7429
+ });
7430
+ }
7431
+ }
7432
+ });
7433
+ return {
7434
+ value: textList.join(""),
7435
+ slotConfig: currentSlotConfig,
7436
+ skill: currentSkill
7437
+ };
7438
+ };
7439
+ const updateSubmitDisabled = () => {
7440
+ const value = getEditorValue();
7441
+ senderCtx.value.setSubmitDisabled?.(!value.value && value.slotConfig.length === 0 && !value.skill);
7442
+ };
7443
+ const triggerValueChange = (event) => {
7444
+ const value = getEditorValue();
7445
+ senderCtx.value.onChange?.(value.value, event, value.slotConfig, value.skill);
7446
+ updateSkillEmptyStatus(value);
7447
+ updateSubmitDisabled();
7448
+ };
7449
+ const updateSlot = (key, value, event) => {
7450
+ slotValues.value = {
7451
+ ...slotValues.value,
7452
+ [key]: value
7453
+ };
7454
+ const config = slotConfigMap.value.get(key);
7455
+ const dom = slotDomMap.value.get(key);
7456
+ if (config && dom && config.type !== "content") renderSlot(config, dom);
7457
+ triggerValueChange(event);
7458
+ };
7459
+ const buildSelectMenuItems = (options) => {
7460
+ return (options ?? []).map((option) => ({
7461
+ label: option,
7462
+ key: option
7463
+ }));
7464
+ };
7465
+ const renderSlot = (config, slotDom) => {
7466
+ if (!("key" in config) || !config.key) return;
7467
+ const slotValue = slotValues.value[config.key];
7468
+ let node = null;
7469
+ switch (config.type) {
7470
+ case "input":
7471
+ node = (0, vue.createVNode)(antdv_next.Input, {
7472
+ "class": `${prefixCls.value}-slot-input`,
7473
+ "placeholder": config.props?.placeholder,
7474
+ "value": slotValue ?? "",
7475
+ "size": "small",
7476
+ "variant": "borderless",
7477
+ "readonly": senderCtx.value.readOnly,
7478
+ "disabled": senderCtx.value.disabled,
7479
+ "onKeydown": onInternalKeyDown,
7480
+ "onChange": (e) => {
7481
+ updateSlot(config.key, e?.target?.value ?? "", e);
7482
+ }
7483
+ }, null);
7484
+ break;
7485
+ case "select": {
7486
+ const displayValue = stringifyValue(slotValue);
7487
+ node = (0, vue.createVNode)(antdv_next.Dropdown, {
7488
+ "disabled": senderCtx.value.readOnly || senderCtx.value.disabled,
7489
+ "trigger": ["click"],
7490
+ "menu": {
7491
+ items: buildSelectMenuItems(config.props?.options),
7492
+ selectable: true,
7493
+ selectedKeys: displayValue ? [displayValue] : [],
7494
+ onSelect: ({ key, domEvent }) => {
7495
+ updateSlot(config.key, key, domEvent);
7496
+ }
7497
+ }
7498
+ }, { default: () => [(0, vue.createVNode)("span", { "class": (0, _v_c_util.classNames)([`${prefixCls.value}-slot-select`, {
7499
+ placeholder: !displayValue,
7500
+ [`${prefixCls.value}-slot-select-selector-value`]: !!displayValue
7501
+ }]) }, [(0, vue.createVNode)("span", {
7502
+ "data-placeholder": config.props?.placeholder,
7503
+ "class": `${prefixCls.value}-slot-select-value`
7504
+ }, [displayValue]), (0, vue.createVNode)("span", { "class": `${prefixCls.value}-slot-select-arrow` }, [(0, vue.createTextVNode)("▼")])])] });
7505
+ break;
7506
+ }
7507
+ case "tag":
7508
+ node = (0, vue.createVNode)("span", { "class": `${prefixCls.value}-slot-tag` }, [config.props?.label ?? config.props?.value ?? ""]);
7509
+ break;
7510
+ case "custom":
7511
+ node = config.customRender?.(slotValue, (nextValue) => {
7512
+ updateSlot(config.key, nextValue);
7513
+ }, {
7514
+ disabled: senderCtx.value.disabled,
7515
+ readOnly: senderCtx.value.readOnly
7516
+ }, config);
7517
+ break;
7518
+ case "content":
7519
+ slotDom.innerText = stringifyValue(slotValue);
7520
+ slotDom.dataset.placeholder = config.props?.placeholder ?? "";
7521
+ return;
7522
+ default: return;
7523
+ }
7524
+ if (!node) return;
7525
+ mountedDomSet.value.add(slotDom);
7526
+ (0, vue.render)(node, slotDom);
7527
+ };
7528
+ const buildSlotNodes = (configs) => {
7529
+ const list = [];
7530
+ configs.forEach((config) => {
7531
+ if (config.type === "text") {
7532
+ list.push(document.createTextNode(config.value || ""));
7533
+ return;
7534
+ }
7535
+ if (!("key" in config) || !config.key) {
7536
+ warning(false, "Sender", "Slot key is missing");
7537
+ return;
7538
+ }
7539
+ slotConfigMap.value.set(config.key, config);
7540
+ if (config.type === "content") {
7541
+ const before = buildSpaceSpan(config.key, "before");
7542
+ const slot = buildEditSlotSpan(config);
7543
+ const after = buildSpaceSpan(config.key, "after");
7544
+ slotValues.value[config.key] = slotValues.value[config.key] ?? getDefaultSlotValue(config);
7545
+ slot.innerText = stringifyValue(slotValues.value[config.key]);
7546
+ slot.dataset.placeholder = config.props?.placeholder ?? "";
7547
+ slotDomMap.value.set(`${config.key}_before`, before);
7548
+ slotDomMap.value.set(config.key, slot);
7549
+ slotDomMap.value.set(`${config.key}_after`, after);
7550
+ list.push(before, slot, after);
7551
+ return;
7552
+ }
7553
+ const slot = buildSlotSpan(config.key);
7554
+ slotValues.value[config.key] = slotValues.value[config.key] ?? getDefaultSlotValue(config);
7555
+ slotDomMap.value.set(config.key, slot);
7556
+ renderSlot(config, slot);
7557
+ list.push(slot);
7558
+ });
7559
+ return list;
7560
+ };
7561
+ const mergeSlotConfig = (configs) => {
7562
+ const nextValues = { ...slotValues.value };
7563
+ configs.forEach((config) => {
7564
+ if ("key" in config && config.key) {
7565
+ slotConfigMap.value.set(config.key, config);
7566
+ if (!(config.key in nextValues)) nextValues[config.key] = getDefaultSlotValue(config);
7567
+ }
7568
+ });
7569
+ slotValues.value = nextValues;
7570
+ };
7571
+ const clearEditor = () => {
7572
+ unmountAllPortals();
7573
+ slotDomMap.value.clear();
7574
+ slotConfigMap.value.clear();
7575
+ slotValues.value = {};
7576
+ currentSkillRef.value = void 0;
7577
+ if (skillDomRef.value) unmountDom(skillDomRef.value);
7578
+ skillDomRef.value = null;
7579
+ if (editableRef.value) editableRef.value.innerHTML = "";
7580
+ };
7581
+ const getSelection = () => {
7582
+ if (typeof window === "undefined") return null;
7583
+ return window.getSelection();
7584
+ };
7585
+ const setRange = (range, selection) => {
7586
+ selection.removeAllRanges();
7587
+ selection.addRange(range);
7588
+ };
7589
+ const setCursorPosition = (targetNode, offset, preventScroll) => {
7590
+ const editable = editableRef.value;
7591
+ if (!editable) return;
7592
+ editable.focus({ preventScroll });
7593
+ const selection = getSelection();
7594
+ if (!selection) return;
7595
+ const range = document.createRange();
7596
+ range.setStart(targetNode, offset);
7597
+ range.collapse(true);
7598
+ setRange(range, selection);
7599
+ };
7600
+ const setStartCursor = (preventScroll) => {
7601
+ const editable = editableRef.value;
7602
+ if (!editable) return;
7603
+ setCursorPosition(editable, skillDomRef.value ? 1 : 0, preventScroll);
7604
+ };
7605
+ const setEndCursor = (preventScroll) => {
7606
+ const editable = editableRef.value;
7607
+ if (!editable) return;
7608
+ editable.focus({ preventScroll });
7609
+ const selection = getSelection();
7610
+ if (!selection) return;
7611
+ const range = document.createRange();
7612
+ range.selectNodeContents(editable);
7613
+ range.collapse(false);
7614
+ setRange(range, selection);
7615
+ };
7616
+ const selectAll = (preventScroll) => {
7617
+ const editable = editableRef.value;
7618
+ if (!editable) return;
7619
+ editable.focus({ preventScroll });
7620
+ const selection = getSelection();
7621
+ if (!selection) return;
7622
+ const range = document.createRange();
7623
+ range.selectNodeContents(editable);
7624
+ if (skillDomRef.value) range.setStart(editable, 1);
7625
+ setRange(range, selection);
7626
+ };
7627
+ const focusSlot = (key, preventScroll) => {
7628
+ const editable = editableRef.value;
7629
+ if (!editable) return;
7630
+ const resolveTarget = (slotKey) => {
7631
+ const slotDom = slotDomMap.value.get(slotKey);
7632
+ const slotCfg = slotConfigMap.value.get(slotKey);
7633
+ if (!slotDom || !slotCfg) return null;
7634
+ if (slotCfg.type === "input") return slotDom.querySelector("input");
7635
+ if (slotCfg.type === "content") return slotDom;
7636
+ return null;
7637
+ };
7638
+ if (key) {
7639
+ const target = resolveTarget(key);
7640
+ if (target instanceof HTMLInputElement) {
7641
+ target.focus({ preventScroll });
7642
+ return;
7643
+ }
7644
+ if (target instanceof HTMLSpanElement) {
7645
+ setCursorPosition(target, 0, preventScroll);
7646
+ return;
7647
+ }
7648
+ }
7649
+ for (const node of Array.from(editable.childNodes)) {
7650
+ if (!(node instanceof HTMLElement)) continue;
7651
+ const slotKey = node.dataset.slotKey;
7652
+ const nodeType = node.dataset.nodeType;
7653
+ if (!slotKey || nodeType === "nbsp") continue;
7654
+ const target = resolveTarget(slotKey);
7655
+ if (target instanceof HTMLInputElement) {
7656
+ target.focus({ preventScroll });
7657
+ return;
7658
+ }
7659
+ if (target instanceof HTMLSpanElement) {
7660
+ setCursorPosition(target, 0, preventScroll);
7661
+ return;
7662
+ }
7663
+ }
7664
+ setEndCursor(preventScroll);
7665
+ };
7666
+ const removeSlot = (key, event) => {
7667
+ const editable = editableRef.value;
7668
+ if (!editable) return;
7669
+ editable.querySelectorAll(`[data-slot-key="${key}"]`).forEach((element) => {
7670
+ unmountDom(element);
7671
+ element.remove();
7672
+ });
7673
+ const nextValues = { ...slotValues.value };
7674
+ delete nextValues[key];
7675
+ slotValues.value = nextValues;
7676
+ slotConfigMap.value.delete(key);
7677
+ slotDomMap.value.delete(key);
7678
+ slotDomMap.value.delete(`${key}_before`);
7679
+ slotDomMap.value.delete(`${key}_after`);
7680
+ triggerValueChange(event);
7681
+ };
7682
+ const removeSkill = (triggerChange = true) => {
7683
+ const skillDom = skillDomRef.value;
7684
+ if (!skillDom) return;
7685
+ unmountDom(skillDom);
7686
+ skillDom.remove();
7687
+ skillDomRef.value = null;
7688
+ currentSkillRef.value = void 0;
7689
+ if (triggerChange) triggerValueChange();
7690
+ };
7691
+ const renderSkill = () => {
7692
+ const editable = editableRef.value;
7693
+ const skill = senderCtx.value.skill;
7694
+ if (!editable) return;
7695
+ if (!skill) {
7696
+ removeSkill(false);
7697
+ return;
7698
+ }
7699
+ let skillDom = skillDomRef.value;
7700
+ if (!skillDom) {
7701
+ skillDom = buildSkillSpan(skill.value);
7702
+ editable.insertBefore(skillDom, editable.firstChild);
7703
+ skillDomRef.value = skillDom;
7704
+ }
7705
+ currentSkillRef.value = skill;
7706
+ mountedDomSet.value.add(skillDom);
7707
+ (0, vue.render)((0, vue.createVNode)(Skill_default, {
7708
+ "prefixCls": prefixCls.value,
7709
+ "skill": skill,
7710
+ "removeSkill": () => removeSkill(true)
7711
+ }, null), skillDom);
7712
+ };
7713
+ const updateSkillEmptyStatus = (value = getEditorValue()) => {
7714
+ const skillDom = skillDomRef.value;
7715
+ if (!skillDom) return;
7716
+ if (!value.value && value.slotConfig.length === 0 && !!senderCtx.value.placeholder) {
7717
+ skillDom.setAttribute("contenteditable", "true");
7718
+ skillDom.classList.add(`${prefixCls.value}-skill-empty`);
7719
+ } else {
7720
+ skillDom.setAttribute("contenteditable", "false");
7721
+ skillDom.classList.remove(`${prefixCls.value}-skill-empty`);
7722
+ }
7723
+ };
7724
+ const initFromSlotConfig = (configs) => {
7725
+ const editable = editableRef.value;
7726
+ if (!editable) return;
7727
+ clearEditor();
7728
+ const mergeConfigs = configs ?? [];
7729
+ mergeConfigs.forEach((config) => {
7730
+ if ("key" in config && config.key) {
7731
+ slotConfigMap.value.set(config.key, config);
7732
+ const defaultValue = getDefaultSlotValue(config);
7733
+ if (defaultValue !== void 0) slotValues.value[config.key] = defaultValue;
7734
+ }
7735
+ });
7736
+ buildSlotNodes(mergeConfigs).forEach((node) => {
7737
+ editable.appendChild(node);
7738
+ });
7739
+ renderSkill();
7740
+ (0, vue.nextTick)(() => {
7741
+ triggerValueChange();
7742
+ });
7743
+ };
7744
+ const removeSpecificBRs = () => {
7745
+ if (senderCtx.value.submitType !== "enter") return;
7746
+ editableRef.value?.querySelectorAll("br").forEach((br) => br.remove());
7747
+ };
7748
+ const shouldSubmit = (event) => {
7749
+ const { key, shiftKey, ctrlKey, altKey, metaKey } = event;
7750
+ if (key !== "Enter") return false;
7751
+ const isModifierPressed = ctrlKey || altKey || metaKey;
7752
+ const submitType = senderCtx.value.submitType ?? "enter";
7753
+ return submitType === "enter" && !shiftKey && !isModifierPressed || submitType === "shiftEnter" && shiftKey && !isModifierPressed;
7754
+ };
7755
+ const findOuterContainer = (node) => {
7756
+ const editable = editableRef.value;
7757
+ if (!node || !editable) return null;
7758
+ let current = node;
7759
+ if (current.nodeType === Node.TEXT_NODE) current = current.parentNode;
7760
+ while (current && current !== editable) {
7761
+ if (current instanceof HTMLElement && current.tagName === "SPAN") return current;
7762
+ current = current.parentNode;
7763
+ }
7764
+ return null;
7765
+ };
7766
+ const handleBackspaceDelete = (event) => {
7767
+ const selection = getSelection();
7768
+ if (!selection || !selection.isCollapsed) return false;
7769
+ const editable = editableRef.value;
7770
+ if (!editable) return false;
7771
+ let anchorNode = selection.anchorNode;
7772
+ let offset = selection.anchorOffset;
7773
+ if (!anchorNode || !editable.contains(anchorNode)) return false;
7774
+ if (anchorNode === editable && offset > 0) {
7775
+ anchorNode = editable.childNodes[offset - 1] ?? anchorNode;
7776
+ offset = 0;
7777
+ }
7778
+ if (anchorNode.nodeType === Node.TEXT_NODE && offset > 0) return false;
7779
+ const target = anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentNode : anchorNode;
7780
+ const previous = target === editable ? editable.childNodes[Math.max(0, selection.anchorOffset - 1)] : target?.previousSibling;
7781
+ if (!(previous instanceof HTMLElement)) return false;
7782
+ const info = getNodeInfo(previous);
7783
+ if (info?.slotKey) {
7784
+ event.preventDefault();
7785
+ removeSlot(info.slotKey, event);
7786
+ return true;
7787
+ }
7788
+ if (info?.skillKey) {
7789
+ event.preventDefault();
7790
+ removeSkill(true);
7791
+ return true;
7792
+ }
7793
+ return false;
7794
+ };
7795
+ const onInternalKeyDown = (event) => {
7796
+ if (senderCtx.value.onKeyDown?.(event) === false || keyLock.value || isComposing.value) return;
7797
+ if (event.key === "Backspace" && handleBackspaceDelete(event)) return;
7798
+ if (shouldSubmit(event)) {
7799
+ event.preventDefault();
7800
+ keyLock.value = true;
7801
+ senderCtx.value.triggerSend?.();
7802
+ return;
7803
+ }
7804
+ if ((event.key === "a" || event.key === "A") && (event.ctrlKey || event.metaKey)) {
7805
+ event.preventDefault();
7806
+ selectAll(true);
7807
+ }
7808
+ };
7809
+ const onInternalKeyUp = (event) => {
7810
+ if (event.key === "Enter") keyLock.value = false;
7811
+ senderCtx.value.onKeyUp?.(event);
7812
+ };
7813
+ const onInternalInput = (event) => {
7814
+ removeSpecificBRs();
7815
+ triggerValueChange(event);
7816
+ };
7817
+ const onInternalPaste = (event) => {
7818
+ event.preventDefault();
7819
+ const files = event.clipboardData?.files;
7820
+ const text = event.clipboardData?.getData("text/plain") ?? "";
7821
+ if (!text && files?.length && senderCtx.value.onPasteFile) {
7822
+ senderCtx.value.onPasteFile(files);
7823
+ return;
7824
+ }
7825
+ if (text) {
7826
+ const selection = getSelection();
7827
+ if (selection && selection.rangeCount > 0) {
7828
+ const range = selection.getRangeAt(0);
7829
+ range.deleteContents();
7830
+ const textNode = document.createTextNode(text.replace(/\u200B/g, ""));
7831
+ range.insertNode(textNode);
7832
+ range.setStartAfter(textNode);
7833
+ range.collapse(true);
7834
+ selection.removeAllRanges();
7835
+ selection.addRange(range);
7836
+ }
7837
+ }
7838
+ onInternalInput(event);
7839
+ senderCtx.value.onPaste?.(event);
7840
+ };
7841
+ const onInternalSelect = () => {
7842
+ const selection = getSelection();
7843
+ const editable = editableRef.value;
7844
+ if (!selection || !editable) return;
7845
+ if (selection.focusNode === editable && selection.focusOffset === 0 && getEditorValue().skill) setCursorPosition(editable, 1);
7846
+ };
7847
+ const getRangeForInsert = (position = "cursor") => {
7848
+ const editable = editableRef.value;
7849
+ if (!editable) return null;
7850
+ const selection = getSelection();
7851
+ const range = document.createRange();
7852
+ if (position === "start") {
7853
+ const index = skillDomRef.value ? 1 : 0;
7854
+ range.setStart(editable, index);
7855
+ range.collapse(true);
7856
+ return {
7857
+ range,
7858
+ selection
7859
+ };
7860
+ }
7861
+ if (position === "end") {
7862
+ range.selectNodeContents(editable);
7863
+ range.collapse(false);
7864
+ return {
7865
+ range,
7866
+ selection
7867
+ };
7868
+ }
7869
+ if (selection && selection.rangeCount > 0 && editable.contains(selection.getRangeAt(0).startContainer)) {
7870
+ const currentRange = selection.getRangeAt(0).cloneRange();
7871
+ const outer = findOuterContainer(currentRange.startContainer);
7872
+ const outerInfo = outer ? getNodeInfo(outer) : null;
7873
+ if (outer && outerInfo?.slotKey && outerInfo.slotConfig?.type !== "content") {
7874
+ currentRange.setStartAfter(outer);
7875
+ currentRange.collapse(true);
7876
+ }
7877
+ return {
7878
+ range: currentRange,
7879
+ selection
7880
+ };
7881
+ }
7882
+ range.selectNodeContents(editable);
7883
+ range.collapse(false);
7884
+ return {
7885
+ range,
7886
+ selection
7887
+ };
7888
+ };
7889
+ const insert = (slotConfig, position = "cursor", replaceCharacters, preventScroll) => {
7890
+ const editable = editableRef.value;
7891
+ if (!editable || !slotConfig.length) return;
7892
+ mergeSlotConfig(slotConfig);
7893
+ const nodes = buildSlotNodes(slotConfig);
7894
+ if (!nodes.length) return;
7895
+ const insertContext = getRangeForInsert(position);
7896
+ if (!insertContext?.range) return;
7897
+ const { range, selection } = insertContext;
7898
+ editable.focus({ preventScroll });
7899
+ if (replaceCharacters) {
7900
+ if ((getSelection()?.toString() ?? "").endsWith(replaceCharacters)) range.setStart(range.startContainer, Math.max(0, range.startOffset - replaceCharacters.length));
7901
+ }
7902
+ range.deleteContents();
7903
+ nodes.forEach((node) => {
7904
+ range.insertNode(node);
7905
+ range.setStartAfter(node);
7906
+ });
7907
+ range.collapse(true);
7908
+ if (selection) {
7909
+ selection.removeAllRanges();
7910
+ selection.addRange(range);
7911
+ }
7912
+ onInternalInput();
7913
+ };
7914
+ const focus = (options) => {
7915
+ const cursor = options?.cursor ?? "end";
7916
+ if (cursor === "start") {
7917
+ setStartCursor(options?.preventScroll);
7918
+ return;
7919
+ }
7920
+ if (cursor === "all") {
7921
+ selectAll(options?.preventScroll);
7922
+ return;
7923
+ }
7924
+ if (cursor === "slot") {
7925
+ focusSlot(options?.key, options?.preventScroll);
7926
+ return;
7927
+ }
7928
+ setEndCursor(options?.preventScroll);
7929
+ };
7930
+ const clear = () => {
7931
+ clearEditor();
7932
+ renderSkill();
7933
+ onInternalInput();
7934
+ };
7935
+ expose({
7936
+ get nativeElement() {
7937
+ return editableRef.value ?? null;
7938
+ },
7939
+ focus,
7940
+ blur() {
7941
+ editableRef.value?.blur();
7942
+ },
7943
+ insert,
7944
+ clear,
7945
+ getValue: getEditorValue
7946
+ });
7947
+ const applySlotConfig = (configs, force = false) => {
7948
+ if (!force && configs === lastSlotConfigRef.value) return;
7949
+ lastSlotConfigRef.value = configs;
7950
+ initFromSlotConfig(configs);
7951
+ };
7952
+ (0, vue.watch)(() => editableRef.value, (editable) => {
7953
+ if (!editable) return;
7954
+ applySlotConfig(senderCtx.value.slotConfig, true);
7955
+ }, { immediate: true });
7956
+ (0, vue.watch)(() => senderCtx.value.slotConfig, (configs) => {
7957
+ applySlotConfig(configs);
7958
+ }, { immediate: true });
7959
+ (0, vue.watch)(() => senderCtx.value.skill, (skill) => {
7960
+ if (skill === lastSkillRef.value && skillDomRef.value) return;
7961
+ lastSkillRef.value = skill;
7962
+ renderSkill();
7963
+ (0, vue.nextTick)(() => {
7964
+ triggerValueChange();
7965
+ });
7966
+ }, { immediate: true });
7967
+ (0, vue.watch)(() => senderCtx.value.readOnly, (readOnly) => {
7968
+ slotConfigMap.value.forEach((config, key) => {
7969
+ if (config.type === "content") slotDomMap.value.get(key)?.setAttribute("contenteditable", readOnly ? "false" : "true");
7970
+ });
7971
+ });
7972
+ (0, vue.onBeforeUnmount)(() => {
7973
+ unmountAllPortals();
7974
+ });
7975
+ return () => {
7976
+ const inputCls = `${prefixCls.value}-input`;
7977
+ return (0, vue.createVNode)("div", {
7978
+ "ref": editableRef,
7979
+ "role": "textbox",
7980
+ "tabindex": 0,
7981
+ "class": (0, _v_c_util.classNames)([
7982
+ inputCls,
7983
+ `${inputCls}-slot`,
7984
+ senderCtx.value.classNames?.input
7985
+ ]),
7986
+ "style": mergeInputStyle.value,
7987
+ "data-placeholder": senderCtx.value.placeholder,
7988
+ "contenteditable": !senderCtx.value.readOnly,
7989
+ "spellcheck": false,
7990
+ "onInput": onInternalInput,
7991
+ "onKeydown": onInternalKeyDown,
7992
+ "onKeyup": onInternalKeyUp,
7993
+ "onPaste": onInternalPaste,
7994
+ "onCut": onInternalInput,
7995
+ "onSelect": onInternalSelect,
7996
+ "onFocus": (e) => {
7997
+ senderCtx.value.onFocus?.(e);
7998
+ },
7999
+ "onBlur": (e) => {
8000
+ keyLock.value = false;
8001
+ senderCtx.value.onBlur?.(e);
8002
+ },
8003
+ "onCompositionstart": () => {
8004
+ isComposing.value = true;
8005
+ },
8006
+ "onCompositionend": () => {
8007
+ isComposing.value = false;
8008
+ keyLock.value = false;
8009
+ }
8010
+ }, null);
8011
+ };
8012
+ }
8013
+ });
8014
+ //#endregion
7214
8015
  //#region components/sender/components/SpeechButton/RecordingIcon.tsx
7215
8016
  var SIZE = 1e3;
7216
8017
  var COUNT = 4;
@@ -7287,15 +8088,6 @@
7287
8088
  }
7288
8089
  });
7289
8090
  //#endregion
7290
- //#region components/sender/context.ts
7291
- var SenderContextKey = Symbol("sender-context");
7292
- function useSenderContext() {
7293
- return (0, vue.inject)(SenderContextKey, (0, vue.computed)(() => ({})));
7294
- }
7295
- function provideSenderContext(value) {
7296
- (0, vue.provide)(SenderContextKey, value);
7297
- }
7298
- //#endregion
7299
8091
  //#region components/sender/components/TextArea.tsx
7300
8092
  var TextArea_default = /* @__PURE__ */ (0, vue.defineComponent)({
7301
8093
  name: "SenderTextArea",
@@ -7506,6 +8298,191 @@
7506
8298
  } };
7507
8299
  };
7508
8300
  //#endregion
8301
+ //#region components/sender/style/slot-textarea.ts
8302
+ var genSlotTextAreaStyle = (token) => {
8303
+ const { componentCls, antCls, calc } = token;
8304
+ const slotCls = `${componentCls}-slot`;
8305
+ const antInputCls = `${antCls}-input`;
8306
+ const antDropdownCls = `${antCls}-dropdown-trigger`;
8307
+ const slotInputCls = `${componentCls}-slot-input`;
8308
+ const slotSelectCls = `${componentCls}-slot-select`;
8309
+ const slotTagCls = `${componentCls}-slot-tag`;
8310
+ const slotContentCls = `${componentCls}-slot-content`;
8311
+ const skillCls = `${componentCls}-skill`;
8312
+ return { [componentCls]: {
8313
+ [`${componentCls}-input-slot`]: {
8314
+ outline: "none",
8315
+ cursor: "text",
8316
+ whiteSpace: "pre-wrap",
8317
+ width: "100%",
8318
+ caretColor: token.colorPrimary,
8319
+ fontSize: token.fontSize,
8320
+ lineHeight: token.lineHeight,
8321
+ [`&:empty::before`]: {
8322
+ content: "attr(data-placeholder)",
8323
+ color: token.colorTextPlaceholder
8324
+ }
8325
+ },
8326
+ [`${slotCls}:not(${slotContentCls})`]: {
8327
+ display: "inline-block",
8328
+ verticalAlign: "middle",
8329
+ alignItems: "center",
8330
+ marginBlock: 1,
8331
+ height: calc(token.fontSize).mul(token.lineHeight).add(2).equal(),
8332
+ wordBreak: "break-all",
8333
+ marginInline: token.marginXXS
8334
+ },
8335
+ [`${antInputCls}${slotInputCls}`]: {
8336
+ height: "100%",
8337
+ background: token.colorBgSlot,
8338
+ outline: "none",
8339
+ color: token.colorTextSlot,
8340
+ borderRadius: token.borderRadius,
8341
+ paddingInline: token.paddingXXS,
8342
+ fontSize: "inherit",
8343
+ lineHeight: "inherit",
8344
+ position: "relative",
8345
+ [`&::placeholder`]: {
8346
+ color: token.colorTextSlotPlaceholder,
8347
+ fontSize: "inherit",
8348
+ lineHeight: "inherit"
8349
+ }
8350
+ },
8351
+ [slotSelectCls]: {
8352
+ fontSize: token.fontSize,
8353
+ lineHeight: token.lineHeight,
8354
+ paddingInline: token.paddingXXS,
8355
+ transition: `border-color ${token.motionDurationMid}`,
8356
+ position: "relative",
8357
+ display: "inline-flex",
8358
+ alignItems: "center",
8359
+ cursor: "pointer",
8360
+ background: token.colorBgSlot,
8361
+ height: "100%",
8362
+ boxSizing: "border-box",
8363
+ borderRadius: token.borderRadius,
8364
+ color: token.colorTextSlot,
8365
+ border: `1px solid ${token.colorBorderSlot}`,
8366
+ [`&.placeholder`]: { color: token.colorTextSlotPlaceholder },
8367
+ [`&${antDropdownCls}-open`]: { borderColor: token.colorBorderSlotHover }
8368
+ },
8369
+ [`${slotSelectCls}-value`]: {
8370
+ flex: 1,
8371
+ fontSize: token.fontSize,
8372
+ lineHeight: token.lineHeight,
8373
+ [`&:empty::before`]: { content: "attr(data-placeholder)" }
8374
+ },
8375
+ [`${slotSelectCls}-arrow`]: {
8376
+ marginInlineStart: token.marginXXS,
8377
+ fontSize: token.fontSize,
8378
+ lineHeight: token.lineHeight,
8379
+ display: "inline-flex",
8380
+ alignItems: "center",
8381
+ justifyContent: "center"
8382
+ },
8383
+ [slotTagCls]: {
8384
+ background: token.colorBgSlot,
8385
+ border: `1px solid ${token.colorBorderSlot}`,
8386
+ outline: "none",
8387
+ color: token.colorTextSlot,
8388
+ borderRadius: token.borderRadius,
8389
+ padding: `0 ${(0, _antdv_next_cssinjs.unit)(token.paddingXXS)}`,
8390
+ fontSize: token.fontSize,
8391
+ lineHeight: token.lineHeight,
8392
+ height: "100%",
8393
+ boxSizing: "border-box",
8394
+ position: "relative",
8395
+ cursor: "default"
8396
+ },
8397
+ [slotContentCls]: {
8398
+ height: calc(token.fontSize).mul(token.lineHeight).add(2).equal(),
8399
+ caretColor: token.colorPrimary,
8400
+ background: token.colorBgSlot,
8401
+ outline: "none",
8402
+ color: token.colorTextSlot,
8403
+ borderRadius: token.borderRadius,
8404
+ paddingInline: token.paddingXXS,
8405
+ boxSizing: "border-box",
8406
+ verticalAlign: "middle",
8407
+ fontSize: token.fontSize,
8408
+ marginBlock: 1,
8409
+ lineHeight: token.lineHeight,
8410
+ display: "inline-block",
8411
+ position: "relative",
8412
+ cursor: "text",
8413
+ [`&:empty`]: {
8414
+ width: "fit-content",
8415
+ [`&::after`]: {
8416
+ display: "inline-block",
8417
+ height: "inherit",
8418
+ content: "attr(data-placeholder)",
8419
+ color: token.colorTextSlotPlaceholder
8420
+ }
8421
+ }
8422
+ },
8423
+ [`${slotCls}-no-width`]: {
8424
+ userSelect: "none",
8425
+ width: "3px",
8426
+ display: "inline-block",
8427
+ lineHeight: "inherit"
8428
+ },
8429
+ [skillCls]: {
8430
+ display: "inline-block",
8431
+ verticalAlign: "baseline",
8432
+ alignItems: "center",
8433
+ marginBlock: 1,
8434
+ height: calc(token.fontSize).mul(token.lineHeight).add(2).equal(),
8435
+ wordBreak: "break-all",
8436
+ paddingInlineEnd: 0,
8437
+ paddingInlineStart: 0,
8438
+ marginInlineEnd: 0,
8439
+ marginInlineStart: -1,
8440
+ [`&${skillCls}-empty`]: { [`&::after`]: {
8441
+ display: "inline-block",
8442
+ pointerEvents: "none",
8443
+ height: "inherit",
8444
+ content: "attr(data-placeholder)",
8445
+ color: token.colorTextPlaceholder
8446
+ } }
8447
+ },
8448
+ [`${skillCls}-wrapper`]: {
8449
+ height: "100%",
8450
+ display: "inline-flex"
8451
+ },
8452
+ [`${skillCls}-tag`]: {
8453
+ paddingInline: token.paddingXS,
8454
+ height: "100%",
8455
+ backgroundColor: token.colorBgSkill,
8456
+ borderRadius: token.borderRadius,
8457
+ color: token.colorPrimary,
8458
+ alignItems: "center",
8459
+ fontWeight: 500,
8460
+ display: "inline-flex",
8461
+ cursor: "pointer",
8462
+ gap: token.marginXXS,
8463
+ transition: `background-color ${token.motionDurationMid}`,
8464
+ [`&:hover`]: {
8465
+ backgroundColor: token.colorBgSkillHover,
8466
+ [`${skillCls}-close:not(${skillCls}-close-disabled)`]: { color: token.colorPrimaryHover }
8467
+ }
8468
+ },
8469
+ [`${skillCls}-close`]: {
8470
+ fontSize: token.fontSizeSM,
8471
+ display: "inline-flex",
8472
+ transition: `color ${token.motionDurationMid}`,
8473
+ color: token.colorPrimary
8474
+ },
8475
+ [`${skillCls}-close-disabled`]: {
8476
+ cursor: "not-allowed",
8477
+ color: token.colorTextDisabled
8478
+ },
8479
+ [`${skillCls}-holder`]: {
8480
+ width: token.marginXS,
8481
+ height: "100%"
8482
+ }
8483
+ } };
8484
+ };
8485
+ //#endregion
7509
8486
  //#region components/sender/style/switch.ts
7510
8487
  var genSenderSwitchStyle = (token) => {
7511
8488
  const { componentCls, antCls } = token;
@@ -7613,12 +8590,26 @@
7613
8590
  };
7614
8591
  var prepareComponentToken$5 = (token) => {
7615
8592
  const { colorPrimary, colorFillTertiary } = token;
8593
+ const colorBgSlot = new _ant_design_fast_color.FastColor(colorPrimary).setA(.06).toRgbString();
8594
+ const colorBgSkill = new _ant_design_fast_color.FastColor(colorPrimary).setA(.08).toRgbString();
8595
+ const colorBgSkillHover = new _ant_design_fast_color.FastColor(colorPrimary).setA(.15).toRgbString();
8596
+ const colorTextSlot = colorPrimary;
8597
+ const colorTextSlotPlaceholder = new _ant_design_fast_color.FastColor(colorPrimary).setA(.25).toRgbString();
8598
+ const colorBorderSlotHover = new _ant_design_fast_color.FastColor(colorPrimary).setA(.1).toRgbString();
8599
+ const colorBorderSlot = colorBgSlot;
7616
8600
  const colorBorderInput = new _ant_design_fast_color.FastColor(colorFillTertiary).setA(.1).toRgbString();
7617
8601
  const switchCheckedBg = new _ant_design_fast_color.FastColor(colorPrimary).setA(.08).toRgbString();
7618
8602
  const switchCheckedHoverBg = new _ant_design_fast_color.FastColor(colorPrimary).setA(.1).toRgbString();
7619
8603
  const switchUncheckedHoverBg = new _ant_design_fast_color.FastColor(colorFillTertiary).setA(.04).toRgbString();
7620
8604
  const colorBgActionsDisabled = new _ant_design_fast_color.FastColor(colorPrimary).setA(.45).toRgbString();
7621
8605
  return {
8606
+ colorBgSlot,
8607
+ colorBgSkill,
8608
+ colorBgSkillHover,
8609
+ colorTextSlot,
8610
+ colorTextSlotPlaceholder,
8611
+ colorBorderSlotHover,
8612
+ colorBorderSlot,
7622
8613
  colorBorderInput,
7623
8614
  switchCheckedBg,
7624
8615
  switchCheckedHoverBg,
@@ -7633,7 +8624,8 @@
7633
8624
  return [
7634
8625
  genSenderStyle(senderToken),
7635
8626
  genSenderHeaderStyle(senderToken),
7636
- genSenderSwitchStyle(senderToken)
8627
+ genSenderSwitchStyle(senderToken),
8628
+ genSlotTextAreaStyle(senderToken)
7637
8629
  ];
7638
8630
  }, prepareComponentToken$5);
7639
8631
  //#endregion
@@ -7692,6 +8684,14 @@
7692
8684
  type: Boolean,
7693
8685
  default: false
7694
8686
  },
8687
+ slotConfig: {
8688
+ type: Array,
8689
+ default: void 0
8690
+ },
8691
+ skill: {
8692
+ type: Object,
8693
+ default: void 0
8694
+ },
7695
8695
  placeholder: {
7696
8696
  type: String,
7697
8697
  default: void 0
@@ -7790,21 +8790,40 @@
7790
8790
  const [hashId, cssVarCls] = style_default$5(prefixCls);
7791
8791
  const containerRef = (0, vue.ref)();
7792
8792
  const inputRef = (0, vue.ref)();
8793
+ const isSlotMode = (0, vue.computed)(() => Array.isArray(props.slotConfig) || !!props.skill?.value);
7793
8794
  const innerValue = (0, vue.ref)(props.defaultValue);
7794
8795
  const mergedValue = (0, vue.computed)(() => props.value ?? innerValue.value);
7795
- const triggerValueChange = (nextValue, event) => {
8796
+ const triggerValueChange = (nextValue, event, slotConfig, skill) => {
7796
8797
  innerValue.value = nextValue;
7797
- props.onChange?.(nextValue, event);
8798
+ props.onChange?.(nextValue, event, slotConfig, skill);
7798
8799
  };
8800
+ const submitDisabled = (0, vue.ref)(!mergedValue.value);
8801
+ (0, vue.watch)(() => mergedValue.value, (next) => {
8802
+ if (!isSlotMode.value) submitDisabled.value = !next;
8803
+ }, { immediate: true });
7799
8804
  const [speechPermission, triggerSpeech, speechRecording] = useSpeech((transcript) => {
8805
+ if (isSlotMode.value) {
8806
+ inputRef.value?.insert?.([{
8807
+ type: "text",
8808
+ value: transcript
8809
+ }]);
8810
+ return;
8811
+ }
7800
8812
  triggerValueChange(`${mergedValue.value} ${transcript}`);
7801
8813
  }, () => props.allowSpeech);
7802
8814
  const triggerSend = () => {
7803
- if (props.onSubmit && !props.loading && mergedValue.value) props.onSubmit(mergedValue.value);
8815
+ if (!props.onSubmit || props.loading || submitDisabled.value) return;
8816
+ const value = inputRef.value?.getValue?.() ?? { value: "" };
8817
+ const slotConfig = "slotConfig" in value ? value.slotConfig : void 0;
8818
+ const skill = "skill" in value ? value.skill : void 0;
8819
+ props.onSubmit(value.value, slotConfig, skill);
7804
8820
  };
7805
8821
  const triggerClear = () => {
8822
+ if (inputRef.value?.clear) {
8823
+ inputRef.value.clear();
8824
+ return;
8825
+ }
7806
8826
  triggerValueChange("");
7807
- inputRef.value?.clear();
7808
8827
  };
7809
8828
  expose({
7810
8829
  get nativeElement() {
@@ -7820,7 +8839,19 @@
7820
8839
  triggerClear();
7821
8840
  },
7822
8841
  insert(text, position) {
7823
- inputRef.value?.insert(text, position);
8842
+ if (isSlotMode.value) {
8843
+ const slotList = Array.isArray(text) ? text : [{
8844
+ type: "text",
8845
+ value: text
8846
+ }];
8847
+ inputRef.value?.insert?.(slotList, position);
8848
+ return;
8849
+ }
8850
+ const textValue = Array.isArray(text) ? text.map((config) => {
8851
+ if (config.type === "text") return config.value ?? "";
8852
+ return config.formatResult?.(config.props?.defaultValue) ?? "";
8853
+ }).join("") : text;
8854
+ inputRef.value?.insert?.(textValue, position);
7824
8855
  },
7825
8856
  getValue() {
7826
8857
  return inputRef.value?.getValue() ?? { value: "" };
@@ -7843,15 +8874,20 @@
7843
8874
  triggerSend,
7844
8875
  placeholder: props.placeholder,
7845
8876
  onFocus: props.onFocus,
7846
- onBlur: props.onBlur
8877
+ onBlur: props.onBlur,
8878
+ slotConfig: props.slotConfig,
8879
+ skill: props.skill,
8880
+ setSubmitDisabled: (disabled) => {
8881
+ submitDisabled.value = disabled;
8882
+ }
7847
8883
  })));
7848
8884
  const actionBtnCls = (0, vue.computed)(() => `${prefixCls.value}-actions-btn`);
7849
8885
  provideActionButtonContext((0, vue.computed)(() => ({
7850
8886
  prefixCls: actionBtnCls.value,
7851
8887
  onSend: triggerSend,
7852
- onSendDisabled: !mergedValue.value,
8888
+ onSendDisabled: submitDisabled.value,
7853
8889
  onClear: triggerClear,
7854
- onClearDisabled: !mergedValue.value,
8890
+ onClearDisabled: submitDisabled.value,
7855
8891
  onCancel: props.onCancel,
7856
8892
  onCancelDisabled: !props.loading,
7857
8893
  onSpeech: () => triggerSpeech(false),
@@ -7904,8 +8940,9 @@
7904
8940
  "class": [`${cls}-content`, props.classNames.content],
7905
8941
  "style": props.styles.content,
7906
8942
  "onMousedown": (e) => {
7907
- if (e.target !== containerRef.value?.querySelector(`.${cls}-input`)) e.preventDefault();
7908
- inputRef.value?.focus();
8943
+ const inputNode = containerRef.value?.querySelector(`.${cls}-input`);
8944
+ if (!isSlotMode.value && e.target !== inputNode) e.preventDefault();
8945
+ if (e.target === inputNode || e.target === containerRef.value) inputRef.value?.focus();
7909
8946
  }
7910
8947
  }, [
7911
8948
  prefixNode && (0, vue.createVNode)("div", {
@@ -7916,7 +8953,7 @@
7916
8953
  ],
7917
8954
  "style": [contextConfig.value.styles?.prefix, props.styles.prefix]
7918
8955
  }, [prefixNode]),
7919
- (0, vue.createVNode)(TextArea_default, { "ref": inputRef }, null),
8956
+ isSlotMode.value ? (0, vue.createVNode)(SlotTextArea_default, { "ref": inputRef }, null) : (0, vue.createVNode)(TextArea_default, { "ref": inputRef }, null),
7920
8957
  suffixNode && (0, vue.createVNode)("div", {
7921
8958
  "class": [
7922
8959
  actionListCls,
@@ -8161,7 +9198,7 @@
8161
9198
  "class": [`${cls}-content`, props.classNames.content],
8162
9199
  "style": props.styles.content
8163
9200
  }, {
8164
- classNames: {
9201
+ classes: {
8165
9202
  icon: props.classNames.icon,
8166
9203
  content: props.classNames.title
8167
9204
  },
@@ -8681,20 +9718,24 @@
8681
9718
  case "ArrowDown":
8682
9719
  offsetRow(1);
8683
9720
  event.preventDefault();
9721
+ event.stopPropagation();
8684
9722
  break;
8685
9723
  case "ArrowUp":
8686
9724
  offsetRow(-1);
8687
9725
  event.preventDefault();
9726
+ event.stopPropagation();
8688
9727
  break;
8689
9728
  case "ArrowRight":
8690
9729
  if (rtl.value) offsetPrev();
8691
9730
  else offsetNext();
8692
9731
  event.preventDefault();
9732
+ event.stopPropagation();
8693
9733
  break;
8694
9734
  case "ArrowLeft":
8695
9735
  if (rtl.value) offsetNext();
8696
9736
  else offsetPrev();
8697
9737
  event.preventDefault();
9738
+ event.stopPropagation();
8698
9739
  break;
8699
9740
  case "Enter":
8700
9741
  event.preventDefault();