@ibiz-template/vue3-components 0.7.41-alpha.38 → 0.7.41-alpha.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/ibiz-markdown-editor-D4Og0fLv.js +1 -0
  2. package/dist/{index-Dp8ExwuL.js → index-BewO9StC.js} +1 -1
  3. package/dist/{index-C28lnh2e.js → index-ClxO69TM.js} +1 -1
  4. package/dist/index-DHKZJQyN.js +11 -0
  5. package/dist/index.min.css +1 -1
  6. package/dist/index.system.min.js +1 -1
  7. package/dist/{wang-editor-DDVqSnRX.js → wang-editor-BYeoazrn.js} +1 -1
  8. package/dist/{xlsx-util-BMANxyk-.js → xlsx-util-DpgMzatq.js} +1 -1
  9. package/es/control/form/form-detail/form-item/form-item-container/form-item-container.mjs +42 -8
  10. package/es/editor/code/code-editor.controller.mjs +72 -25
  11. package/es/editor/code/monaco-editor/monaco-editor.css +1 -1
  12. package/es/editor/code/monaco-editor/monaco-editor.mjs +20 -8
  13. package/es/editor/html/html-editor.controller.mjs +49 -4
  14. package/es/editor/html/wang-editor/wang-editor.mjs +7 -1
  15. package/es/editor/markdown/ibiz-markdown-editor/custom-menu.mjs +5 -7
  16. package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
  17. package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.mjs +42 -4
  18. package/es/editor/markdown/markdown-editor.controller.mjs +111 -6
  19. package/es/locale/en/index.mjs +5 -2
  20. package/es/locale/zh-CN/index.mjs +5 -2
  21. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -1
  22. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.mjs +76 -21
  23. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.mjs +48 -33
  24. package/lib/control/form/form-detail/form-item/form-item-container/form-item-container.cjs +42 -8
  25. package/lib/editor/code/code-editor.controller.cjs +72 -25
  26. package/lib/editor/code/monaco-editor/monaco-editor.cjs +20 -8
  27. package/lib/editor/code/monaco-editor/monaco-editor.css +1 -1
  28. package/lib/editor/html/html-editor.controller.cjs +49 -4
  29. package/lib/editor/html/wang-editor/wang-editor.cjs +7 -1
  30. package/lib/editor/markdown/ibiz-markdown-editor/custom-menu.cjs +5 -7
  31. package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.cjs +42 -4
  32. package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
  33. package/lib/editor/markdown/markdown-editor.controller.cjs +111 -6
  34. package/lib/locale/en/index.cjs +5 -2
  35. package/lib/locale/zh-CN/index.cjs +5 -2
  36. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.cjs +48 -33
  37. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -1
  38. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.cjs +76 -21
  39. package/package.json +4 -4
  40. package/dist/ibiz-markdown-editor-qRaayafj.js +0 -1
  41. package/dist/index-BiYphJ2f.js +0 -11
@@ -89,6 +89,20 @@ class MarkDownEditorController extends EditorController {
89
89
  * @memberof MarkDownEditorController
90
90
  */
91
91
  __publicField(this, "selectionAreaPosition", null);
92
+ /**
93
+ * 选区方向 true表示正向,从左到右;false表示反向,从右到左
94
+ *
95
+ * @type {boolean}
96
+ * @memberof MarkDownEditorController
97
+ */
98
+ __publicField(this, "selectionDirection", true);
99
+ /**
100
+ * 当前编辑器使用主题
101
+ *
102
+ * @type {string}
103
+ * @memberof MarkDownEditorController
104
+ */
105
+ __publicField(this, "currentEditorTheme", "light");
92
106
  }
93
107
  async onInit() {
94
108
  await super.onInit();
@@ -174,6 +188,33 @@ class MarkDownEditorController extends EditorController {
174
188
  setCursorPos(start, end) {
175
189
  this.selectionAreaPosition = { start, end };
176
190
  }
191
+ /**
192
+ * 设置当前编辑器的主题
193
+ *
194
+ * @param {string} theme
195
+ * @memberof MarkDownEditorController
196
+ */
197
+ setCurrentEditorTheme(theme) {
198
+ this.currentEditorTheme = theme;
199
+ }
200
+ /**
201
+ * 设置当前选区方向
202
+ *
203
+ * @param {boolean} direction
204
+ * @memberof MarkDownEditorController
205
+ */
206
+ setSelectionDirection(direction) {
207
+ this.selectionDirection = direction;
208
+ }
209
+ /**
210
+ * 获取当前主题
211
+ *
212
+ * @return {*} {('light' | 'dark')}
213
+ * @memberof MarkDownEditorController
214
+ */
215
+ getCurrentTheme() {
216
+ return this.currentEditorTheme === "dark" ? "dark" : "light";
217
+ }
177
218
  /**
178
219
  * 获取选中文本
179
220
  *
@@ -184,6 +225,30 @@ class MarkDownEditorController extends EditorController {
184
225
  var _a;
185
226
  return (_a = this.mdeditor) == null ? void 0 : _a.editor.editor.getSelection();
186
227
  }
228
+ /**
229
+ * 获取内联AI编辑器主题
230
+ *
231
+ * @return {*} {('light' | 'dark')}
232
+ * @memberof MarkDownEditorController
233
+ */
234
+ getInLineAiEditorTheme() {
235
+ return this.getCurrentTheme();
236
+ }
237
+ /**
238
+ * 判断选区方向
239
+ *
240
+ * @param {IData} posA
241
+ * @param {IData} posB
242
+ * @return {*} {boolean}
243
+ * @memberof MarkDownEditorController
244
+ */
245
+ isPositionBefore(posA, posB) {
246
+ if (posA.line < posB.line)
247
+ return true;
248
+ if (posA.line > posB.line)
249
+ return false;
250
+ return posA.ch < posB.ch;
251
+ }
187
252
  /**
188
253
  * 插入文本
189
254
  *
@@ -191,8 +256,32 @@ class MarkDownEditorController extends EditorController {
191
256
  * @memberof MarkDownEditorController
192
257
  */
193
258
  insertText(text) {
194
- var _a;
195
- (_a = this.mdeditor) == null ? void 0 : _a.insert(text);
259
+ var _a, _b, _c;
260
+ if (this.selectionAreaPosition) {
261
+ const { start, end } = this.selectionAreaPosition;
262
+ const contentToInsert = "\n".concat(text, "\n");
263
+ const hasSelection = !(start.line === end.line && start.ch === end.ch);
264
+ if (!hasSelection) {
265
+ (_a = this.mdeditor) == null ? void 0 : _a.editor.editor.replaceSelection(contentToInsert);
266
+ return;
267
+ }
268
+ let insetPos;
269
+ if (this.selectionDirection) {
270
+ insetPos = end;
271
+ } else {
272
+ insetPos = start;
273
+ }
274
+ (_b = this.mdeditor) == null ? void 0 : _b.editor.editor.setCursor(insetPos);
275
+ (_c = this.mdeditor) == null ? void 0 : _c.editor.editor.replaceSelection(contentToInsert);
276
+ if (this.selectionDirection === false) {
277
+ const index = (contentToInsert.match(/\n/g) || []).length;
278
+ this.selectionAreaPosition.start.line += index;
279
+ this.selectionAreaPosition.end.line += index;
280
+ this.selectionAreaPosition.end.ch -= this.selectionAreaPosition.start.ch;
281
+ this.selectionAreaPosition.start.ch = 0;
282
+ }
283
+ this.restoreSelection();
284
+ }
196
285
  }
197
286
  /**
198
287
  * 替换选中文本
@@ -223,14 +312,30 @@ class MarkDownEditorController extends EditorController {
223
312
  * @memberof MarkDownEditorController
224
313
  */
225
314
  getInLineAiChatOptions() {
226
- var _a;
315
+ var _a, _b, _c;
227
316
  const editorRect = (_a = this.mdeditor) == null ? void 0 : _a.wrapperDom.getBoundingClientRect();
317
+ const bubbleRect = (_b = this.mdeditor) == null ? void 0 : _b.bubble.bubbleDom.getBoundingClientRect();
228
318
  return {
229
- left: editorRect == null ? void 0 : editorRect.left,
230
- top: editorRect == null ? void 0 : editorRect.top,
231
- width: editorRect == null ? void 0 : editorRect.width
319
+ // 编辑器的左侧距离 + 10px
320
+ left: editorRect.left + 10,
321
+ // 浮动工具栏的顶部距离位置
322
+ top: bubbleRect.top,
323
+ // 编辑器的宽度 - 右侧工具栏的宽度(38px) - 左侧边距(10px)- 右侧边距(10px)
324
+ width: editorRect.width - 58,
325
+ editorElement: (_c = this.mdeditor) == null ? void 0 : _c.wrapperDom,
326
+ editorTheme: this.getCurrentTheme()
232
327
  };
233
328
  }
329
+ /**
330
+ * 返回内联AI编辑器元素
331
+ *
332
+ * @return {*} {Element}
333
+ * @memberof MarkDownEditorController
334
+ */
335
+ getInLineAiEditorElement() {
336
+ var _a;
337
+ return (_a = this.mdeditor) == null ? void 0 : _a.wrapperDom;
338
+ }
234
339
  /**
235
340
  * 执行内联AIUI操作
236
341
  *
@@ -625,7 +625,8 @@ var index = {
625
625
  noEditorArea: "Editor content area not found",
626
626
  noSelStart: "No start position of current selection",
627
627
  noEditorRect: "No editor DOM node position info",
628
- noSelCoords: "No scroll coordinates of selection"
628
+ noSelCoords: "No scroll coordinates of selection",
629
+ editorNotInit: "Editor not initialized"
629
630
  },
630
631
  dateRange: {
631
632
  rangeSeparator: "To"
@@ -842,7 +843,9 @@ var index = {
842
843
  replaceText: "Replace Text",
843
844
  copyText: "Copy Text",
844
845
  info: "The content is generated by AI, please carefully discern.",
845
- stopEdit: "Terminate editing"
846
+ stopEdit: "Terminate editing",
847
+ warningTitle: "Confirm termination",
848
+ warningDesc: "Are you sure to terminate the creation?"
846
849
  }
847
850
  },
848
851
  // runTime
@@ -621,7 +621,8 @@ var index = {
621
621
  noEditorArea: "\u672A\u627E\u5230\u7F16\u8F91\u5668\u5185\u5BB9\u533A\u57DF",
622
622
  noSelStart: "\u672A\u83B7\u53D6\u5230\u5F53\u524D\u9009\u4E2D\u533A\u57DF\u7684\u8D77\u59CB\u4F4D\u7F6E",
623
623
  noEditorRect: "\u672A\u83B7\u53D6\u5230\u7F16\u8F91\u5668DOM\u8282\u70B9\u7684\u4F4D\u7F6E\u4FE1\u606F",
624
- noSelCoords: "\u672A\u8BA1\u7B97\u51FA\u9009\u4E2D\u4F4D\u7F6E\u7684\u6EDA\u52A8\u53EF\u89C6\u5750\u6807"
624
+ noSelCoords: "\u672A\u8BA1\u7B97\u51FA\u9009\u4E2D\u4F4D\u7F6E\u7684\u6EDA\u52A8\u53EF\u89C6\u5750\u6807",
625
+ editorNotInit: "\u7F16\u8F91\u5668\u672A\u521D\u59CB\u5316"
625
626
  },
626
627
  dateRange: {
627
628
  rangeSeparator: "\u81F3"
@@ -838,7 +839,9 @@ var index = {
838
839
  replaceText: "\u66FF\u6362\u6587\u672C",
839
840
  copyText: "\u590D\u5236\u6587\u672C",
840
841
  info: "\u5185\u5BB9\u7531 AI \u751F\u6210\uFF0C\u8BF7\u4ED4\u7EC6\u7504\u522B\u3002",
841
- stopEdit: "\u7EC8\u6B62\u7F16\u8F91"
842
+ stopEdit: "\u7EC8\u6B62\u7F16\u8F91",
843
+ warningTitle: "\u786E\u8BA4\u4E2D\u6B62",
844
+ warningDesc: "\u786E\u8BA4\u4E2D\u6B62\u521B\u4F5C\u5417\uFF1F"
842
845
  }
843
846
  },
844
847
  // runTime
@@ -1 +1 @@
1
- .ibiz-inline-ai-container-context-menu{--ibiz-inline-ai-context-menu-color-bg:var(--ibiz-color-bg-2);--ibiz-inline-ai-context-menu-color-text:var(--ibiz-color-text-0);--ibiz-inline-ai-context-menu-color-bg-active:var(--ibiz-color-fill-0);--mx-menu-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-backgroud:var(--ibiz-inline-ai-context-menu-color-bg);--mx-menu-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-open-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active)}.ibiz-inline-ai-container-context-menu .scroll-content{pointer-events:unset}.ibiz-inline-ai-container-context-menu .mx-context-menu{cursor:pointer}.ibiz-inline-ai-textarea-container{position:absolute;z-index:99999999;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:var(--ibiz-color-bg-1);border:1px solid var(--ibiz-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:rgba(0,0,0,.08) 0 0 16px 0}.ibiz-inline-ai-textarea-container__content{position:relative;display:flex;gap:var(--ibiz-spacing-tight);padding:var(--ibiz-spacing-base-tight)}.ibiz-inline-ai-textarea-container__content--prefix{flex-shrink:0}.ibiz-inline-ai-textarea-container__content--ai-icon{color:var(--ibiz-color-disabled-text)}.ibiz-inline-ai-textarea-container__content--textarea{position:relative;flex-grow:1}.ibiz-inline-ai-textarea-container__content--textarea textarea{width:100%;height:100%;padding:0;resize:none;border:none;outline:0}.ibiz-inline-ai-textarea-container__content--textarea textarea:disabled{background-color:var(--ibiz-color-bg-1)}.ibiz-inline-ai-textarea-container__content--suffix{display:flex;flex-direction:column-reverse;flex-shrink:0}.ibiz-inline-ai-textarea-container__content--sand-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;color:var(--ibiz-color-primary);cursor:pointer;border-radius:var(--ibiz-spacing-extra-tight)}.ibiz-inline-ai-textarea-container__content--sand-icon:hover{background-color:var(--ibiz-color-primary-light-default)}.ibiz-inline-ai-textarea-container__content--stop-icon{display:flex;gap:var(--ibiz-spacing-extra-tight);align-items:center;font-size:var(--ibiz-font-size-small);color:var(--ibiz-color-disabled-text);cursor:pointer}.ibiz-inline-ai-textarea-container__content--stop-icon:hover{color:var(--ibiz-color-primary-hover)}.ibiz-inline-ai-textarea-container__footer{padding:var(--ibiz-spacing-base-tight) var(--ibiz-spacing-base);font-size:var(--ibiz-font-size-small);color:var(--ibiz-color-disabled-text);background-color:var(--ibiz-color-disabled-fill);border-top:1px solid var(--ibiz-color-disabled-border)}.ibiz-inline-ai-textarea-container__actions{position:absolute;width:240px;padding:var(--ibiz-spacing-base-tight) 0;font-size:var(--ibiz-font-size-regular);visibility:hidden;background-color:var(--ibiz-color-bg-1);border:1px solid var(--ibiz-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:rgba(0,0,0,.08) 0 0 16px 0}.ibiz-inline-ai-textarea-container__actions.is-show{visibility:visible}.ibiz-inline-ai-textarea-container__actions--action{display:flex;gap:var(--ibiz-spacing-tight);align-items:center;padding:var(--ibiz-spacing-tight) var(--ibiz-spacing-base-loose);cursor:pointer}.ibiz-inline-ai-textarea-container__actions--action:hover{background-color:var(--ibiz-color-fill-0)}.ibiz-inline-ai-textarea-container__actions--action.is-danger:hover{color:var(--ibiz-color-danger)}.ibiz-inline-ai-textarea-container__actions--divider{margin:var(--ibiz-spacing-extra-tight) var(--ibiz-spacing-base-loose);border-top:1px solid var(--ibiz-color-border)}
1
+ .ibiz-inline-ai-container-context-menu{--ibiz-inline-ai-context-menu-color-bg:var(--ibiz-color-bg-2);--ibiz-inline-ai-context-menu-color-text:var(--ibiz-color-text-0);--ibiz-inline-ai-context-menu-color-bg-active:var(--ibiz-color-fill-0);--mx-menu-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-backgroud:var(--ibiz-inline-ai-context-menu-color-bg);--mx-menu-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-open-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-active-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-active-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-backgroud-radius:0}.ibiz-inline-ai-container-context-menu .scroll-content{pointer-events:unset}.ibiz-inline-ai-container-context-menu .mx-context-menu-item{cursor:pointer}.ibiz-inline-ai-textarea-container{--ibiz-inline-ai-textarea-container-color-bg-0:rgb(255, 255, 255);--ibiz-inline-ai-textarea-container-color-bg-1:rgb(249, 249, 249);--ibiz-inline-ai-textarea-container-color-border:rgba(29, 31, 35, 0.1);--ibiz-inline-ai-textarea-container-color-text-0:rgb(29, 31, 35);--ibiz-inline-ai-textarea-container-color-text-1:rgba(29, 31, 35, 0.35);--ibiz-inline-ai-textarea-container-color-text-2:rgb(85, 125, 165);--ibiz-inline-ai-textarea-container-color-text-hove-1:rgb(105, 148, 190);--ibiz-inline-ai-textarea-container-color-bg-hover-1:rgb(217, 236, 255);--ibiz-inline-ai-textarea-container-color-bg-hover-2:rgba(46, 50, 55, 0.05);--ibiz-inline-ai-textarea-container-color-loading:#65b3fc}.ibiz-inline-ai-textarea-container--dark{--ibiz-inline-ai-textarea-container-color-bg-0:rgb(28, 28, 28);--ibiz-inline-ai-textarea-container-color-bg-1:rgb(53, 54, 60);--ibiz-inline-ai-textarea-container-color-border:rgba(255, 255, 255, 0.08);--ibiz-inline-ai-textarea-container-color-text-0:rgb(255, 255, 255);--ibiz-inline-ai-textarea-container-color-text-1:rgba(249, 249, 249, 0.35);--ibiz-inline-ai-textarea-container-color-text-2:rgb(70, 107, 144);--ibiz-inline-ai-textarea-container-color-text-hove-1:rgb(105, 148, 190);--ibiz-inline-ai-textarea-container-color-bg-hover-1:rgba(85, 125, 165, 0.2);--ibiz-inline-ai-textarea-container-color-bg-hover-2:rgb(67, 68, 74);--ibiz-inline-ai-textarea-container-color-loading:rgba(204, 204, 204, 0.6)}.ibiz-inline-ai-textarea-container{position:absolute;z-index:2000;color:var(--ibiz-inline-ai-textarea-container-color-text-0);-webkit-user-select:none;-moz-user-select:none;user-select:none}.ibiz-inline-ai-textarea-container .ibiz-inline-ai-textarea-container__content{border:1px solid var(--ibiz-inline-ai-textarea-container-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:0 0 16px var(--ibiz-color-shadow)}.ibiz-inline-ai-textarea-container.is-show-ai{border:1px solid var(--ibiz-inline-ai-textarea-container-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:0 0 16px var(--ibiz-color-shadow)}.ibiz-inline-ai-textarea-container.is-show-ai .ibiz-inline-ai-textarea-container__content{border:none;border-radius:var(--ibiz-border-radius-small) var(--ibiz-border-radius-small) 0 0;box-shadow:none}.ibiz-inline-ai-textarea-container.is-show-ai .ibiz-inline-ai-textarea-container__footer{border-radius:0 0 var(--ibiz-border-radius-small) var(--ibiz-border-radius-small)}.ibiz-inline-ai-textarea-container__content{position:relative;display:flex;gap:var(--ibiz-spacing-tight);padding:var(--ibiz-spacing-base-tight);background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0)}.ibiz-inline-ai-textarea-container__content--prefix{flex-shrink:0;color:var(--ibiz-inline-ai-textarea-container-color-text-1)}.ibiz-inline-ai-textarea-container__content--textarea{position:relative;flex-grow:1}.ibiz-inline-ai-textarea-container__content--textarea textarea{width:100%;height:100%;padding:0;color:var(--ibiz-inline-ai-textarea-container-color-text-0);resize:none;background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0);border:none;outline:0}.ibiz-inline-ai-textarea-container__content--textarea textarea:disabled{background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0)}.ibiz-inline-ai-textarea-container__content--suffix{display:flex;flex-direction:column-reverse;flex-shrink:0}.ibiz-inline-ai-textarea-container__content--sand-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;color:var(--ibiz-inline-ai-textarea-container-color-text-2);cursor:pointer;border-radius:var(--ibiz-spacing-extra-tight)}.ibiz-inline-ai-textarea-container__content--sand-icon:hover{background-color:var(--ibiz-inline-ai-textarea-container-color-bg-hover-1)}.ibiz-inline-ai-textarea-container__content--stop-icon{display:flex;gap:var(--ibiz-spacing-extra-tight);align-items:center;font-size:var(--ibiz-font-size-small);color:var(--ibiz-inline-ai-textarea-container-color-text-1);cursor:pointer}.ibiz-inline-ai-textarea-container__content--stop-icon:hover{color:var(--ibiz-inline-ai-textarea-container-color-text-hove-1)}.ibiz-inline-ai-textarea-container__footer{padding:var(--ibiz-spacing-base-tight) var(--ibiz-spacing-base);font-size:var(--ibiz-font-size-small);color:var(--ibiz-inline-ai-textarea-container-color-text-1);visibility:hidden;background-color:var(--ibiz-inline-ai-textarea-container-color-bg-1);border-top:1px solid var(--ibiz-inline-ai-textarea-container-color-border)}.ibiz-inline-ai-textarea-container__footer.is-show{visibility:visible}.ibiz-inline-ai-textarea-container__actions{position:absolute;width:240px;padding:var(--ibiz-spacing-base-tight) 0;font-size:var(--ibiz-font-size-regular);visibility:hidden;background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0);border:1px solid var(--ibiz-inline-ai-textarea-container-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:0 0 16px var(--ibiz-color-shadow)}.ibiz-inline-ai-textarea-container__actions.is-show{visibility:visible}.ibiz-inline-ai-textarea-container__actions--action{display:flex;gap:var(--ibiz-spacing-tight);align-items:center;padding:var(--ibiz-spacing-tight) var(--ibiz-spacing-base-loose);cursor:pointer}.ibiz-inline-ai-textarea-container__actions--action:hover{background-color:var(--ibiz-inline-ai-textarea-container-color-bg-hover-2)}.ibiz-inline-ai-textarea-container__actions--action.is-danger:hover{color:var(--ibiz-color-danger)}.ibiz-inline-ai-textarea-container__actions--divider{margin:var(--ibiz-spacing-extra-tight) var(--ibiz-spacing-base-loose);border-top:1px solid var(--ibiz-inline-ai-textarea-container-color-border)}.ibiz-inline-ai-textarea-container__loading{position:absolute;top:0;left:0;display:flex;gap:8px;align-items:center;width:100%;height:100%;overflow:hidden}@keyframes bounce{0%,100%,80%{transform:scale(0)}40%{transform:scale(1)}}.ibiz-inline-ai-textarea-container__loading--dot{width:12px;height:12px;background:var(--ibiz-inline-ai-textarea-container-color-loading);border-radius:50%;animation:bounce 1.5s infinite ease-in-out}.ibiz-inline-ai-textarea-container__loading--dot:nth-child(2){animation-delay:.2s}.ibiz-inline-ai-textarea-container__loading--dot:nth-child(3){animation-delay:.4s}
@@ -8,14 +8,27 @@ const computedInLineAIParams = (props) => {
8
8
  return {
9
9
  srfaiappendcurdata: (_a = props.context.srfaiappendcurdata) != null ? _a : true,
10
10
  srfaiautoappend: props.params.srfaiautoappend === "true" || props.params.srfaiautoappend === true,
11
- srfmode: props.params.srfmode
11
+ srfmode: props.params.srfmode,
12
+ srfaiagent: props.params.srfaiagent
12
13
  };
13
14
  };
14
- const useInLineAIContainerClick = (props) => {
15
- const handclick = (evt) => {
15
+ const useInLineAIContainerClick = (props, content, isLoading) => {
16
+ const handclick = async (evt) => {
16
17
  const target = evt.target;
17
- if (!target.closest(".ibiz-inline-ai-textarea-container")) {
18
- props.unMountAIChat();
18
+ if (!target.closest(".ibiz-inline-ai-textarea-container") && !target.closest(".ibiz-inline-ai-alert") && !isLoading.value) {
19
+ const isChange = props.content !== content.value;
20
+ let isClose = true;
21
+ if (isChange) {
22
+ isClose = await ibiz.confirm.warning({
23
+ title: ibiz.i18n.t("util.inlineAiUtil.warningTitle"),
24
+ desc: ibiz.i18n.t("util.inlineAiUtil.warningDesc"),
25
+ options: {
26
+ modalClass: "ibiz-inline-ai-alert"
27
+ }
28
+ });
29
+ }
30
+ if (isClose)
31
+ props.unMountAIChat();
19
32
  }
20
33
  };
21
34
  onMounted(() => {
@@ -27,7 +40,7 @@ const useInLineAIContainerClick = (props) => {
27
40
  };
28
41
  const useAI = (props, opts) => {
29
42
  const { context, data, deACMode } = props;
30
- const { srfaiappendcurdata, srfmode } = opts;
43
+ const { srfaiappendcurdata, srfmode, srfaiagent } = opts;
31
44
  const params = { srfactag: deACMode.codeName };
32
45
  const app = ibiz.hub.getApp(deACMode.appId);
33
46
  let history = [];
@@ -48,6 +61,8 @@ const useAI = (props, opts) => {
48
61
  Object.assign(body, { data });
49
62
  if (srfmode)
50
63
  Object.assign(body, { mode: srfmode });
64
+ if (srfaiagent)
65
+ Object.assign(body, { srfaiagent });
51
66
  const response = await app.net.post(path, body, params);
52
67
  if (response.ok && Array.isArray(response.data)) {
53
68
  history = response.data.filter(
@@ -68,6 +83,8 @@ const useAI = (props, opts) => {
68
83
  };
69
84
  if (srfmode)
70
85
  Object.assign(body, { mode: srfmode });
86
+ if (srfaiagent)
87
+ Object.assign(body, { srfaiagent });
71
88
  const appDataEntity = await ibiz.hub.getAppDataEntity(
72
89
  deACMode.appDataEntityId,
73
90
  deACMode.appId
@@ -123,24 +140,47 @@ const useBase = (props, container, target) => {
123
140
  actionName: "cancel"
124
141
  }
125
142
  ];
143
+ const { options } = props;
144
+ const editorRect = options.editorElement.getBoundingClientRect();
145
+ const offsetX = options.left - editorRect.left;
146
+ const offsetY = options.top - editorRect.top;
147
+ const theme = options.editorTheme || "light";
126
148
  const actionStyle = ref({});
127
149
  const containerStyle = ref({
128
- width: "".concat(props.options.width, "px"),
129
- left: "".concat(props.options.left, "px"),
130
- top: "".concat(props.options.top, "px")
150
+ width: "".concat(options.width, "px"),
151
+ left: "".concat(options.left, "px"),
152
+ top: "".concat(options.top, "px")
131
153
  });
132
154
  const contentStyle = ref({
133
- height: "".concat(props.options.height || 80, "px"),
134
- "max-height": "".concat(props.options.maxHeight, "px")
155
+ height: "".concat(options.height || 80, "px"),
156
+ "max-height": "".concat(options.maxHeight, "px")
135
157
  });
136
- const calcStyle = (isInit = false) => {
158
+ const updatePosition = () => {
137
159
  if (!container.value || !target.value)
138
160
  return;
139
- const containerRect = container.value.getBoundingClientRect();
161
+ const rect = options.editorElement.getBoundingClientRect();
162
+ let top = rect.top + offsetY;
163
+ let left = rect.left + offsetX;
164
+ const containerWidth = container.value.offsetWidth;
165
+ const containerHeight = container.value.offsetHeight;
166
+ const windowWidth = window.innerWidth;
167
+ const windowHeight = window.innerHeight;
168
+ const margin = 8;
169
+ if (left + containerWidth + margin > windowWidth) {
170
+ left = windowWidth - containerWidth - margin;
171
+ } else if (left < margin) {
172
+ left = margin;
173
+ }
174
+ if (top + containerHeight + margin > windowHeight) {
175
+ top = windowHeight - containerHeight - margin;
176
+ } else if (top < margin) {
177
+ top = margin;
178
+ }
179
+ containerStyle.value.top = "".concat(top, "px");
180
+ containerStyle.value.left = "".concat(left, "px");
181
+ const position = containerHeight + 4;
140
182
  const targetHeight = target.value.offsetHeight;
141
- const spaceBelow = window.innerHeight - containerRect.bottom;
142
- const position = (isInit ? containerRect.height + 41 : containerRect.height) + 4;
143
- if (spaceBelow >= targetHeight + 8) {
183
+ if (windowHeight - (top + containerHeight + targetHeight) > margin) {
144
184
  actionStyle.value.top = "".concat(position, "px");
145
185
  actionStyle.value.bottom = "auto";
146
186
  } else {
@@ -148,15 +188,30 @@ const useBase = (props, container, target) => {
148
188
  actionStyle.value.top = "auto";
149
189
  }
150
190
  };
151
- const updatePosition = () => calcStyle();
191
+ let ticking = false;
192
+ const optimizedUpdatePosition = () => {
193
+ if (!ticking) {
194
+ requestAnimationFrame(() => {
195
+ updatePosition();
196
+ ticking = false;
197
+ });
198
+ ticking = true;
199
+ }
200
+ };
152
201
  onMounted(() => {
153
- calcStyle(true);
154
- window.addEventListener("resize", updatePosition, { passive: true });
202
+ updatePosition();
203
+ document.addEventListener("scroll", optimizedUpdatePosition, {
204
+ capture: true
205
+ });
206
+ window.addEventListener("resize", optimizedUpdatePosition);
155
207
  });
156
208
  onUnmounted(() => {
157
- window.removeEventListener("resize", updatePosition);
209
+ document.removeEventListener("scroll", optimizedUpdatePosition, {
210
+ capture: true
211
+ });
212
+ window.removeEventListener("resize", optimizedUpdatePosition);
158
213
  });
159
- return { actions, actionStyle, containerStyle, contentStyle };
214
+ return { theme, actions, actionStyle, containerStyle, contentStyle };
160
215
  };
161
216
 
162
217
  export { computedInLineAIParams, useAI, useBase, useInLineAIContainerClick };
@@ -52,32 +52,45 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
52
52
  const ns = useNamespace("inline-ai-textarea-container");
53
53
  const containerRef = ref();
54
54
  const actionsRef = ref();
55
+ const textareaRef = ref();
56
+ const textareaContent = ref(props.content);
57
+ let question;
58
+ const contentType = ref("USER");
59
+ const isLoading = ref(false);
60
+ const disabled = computed(() => {
61
+ return contentType.value === "ASSISTANT" || isLoading.value;
62
+ });
63
+ const isShow = computed(() => {
64
+ return contentType.value === "ASSISTANT" && !isLoading.value;
65
+ });
55
66
  const {
56
67
  srfaiappendcurdata,
57
68
  srfaiautoappend,
58
- srfmode
69
+ srfmode,
70
+ srfaiagent
59
71
  } = computedInLineAIParams(props);
60
72
  const {
73
+ theme,
61
74
  actions,
62
75
  actionStyle,
63
76
  containerStyle,
64
77
  contentStyle
65
78
  } = useBase(props, containerRef, actionsRef);
66
- useInLineAIContainerClick(props);
79
+ useInLineAIContainerClick(props, textareaContent, isLoading);
67
80
  const {
68
81
  askAI
69
82
  } = useAI(props, {
70
83
  srfaiappendcurdata,
71
- srfmode
72
- });
73
- const textareaContent = ref(props.content);
74
- let question;
75
- const contentType = ref("USER");
76
- const isLoading = ref(false);
77
- const disabled = computed(() => {
78
- return contentType.value === "ASSISTANT" || isLoading.value;
84
+ srfmode,
85
+ srfaiagent
79
86
  });
87
+ const restoreFocus = () => {
88
+ var _a;
89
+ (_a = textareaRef.value) == null ? void 0 : _a.blur();
90
+ props.restoreSelection();
91
+ };
80
92
  const sendQuestion = async (content) => {
93
+ restoreFocus();
81
94
  question = content;
82
95
  textareaContent.value = "";
83
96
  isLoading.value = true;
@@ -122,15 +135,22 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
122
135
  }
123
136
  };
124
137
  onMounted(() => {
125
- if (srfaiautoappend)
138
+ var _a;
139
+ if (srfaiautoappend) {
126
140
  sendQuestion(textareaContent.value);
141
+ } else {
142
+ (_a = textareaRef.value) == null ? void 0 : _a.focus();
143
+ }
127
144
  });
128
145
  return {
129
146
  ns,
147
+ theme,
148
+ isShow,
130
149
  actions,
150
+ disabled,
131
151
  isLoading,
132
152
  actionsRef,
133
- disabled,
153
+ textareaRef,
134
154
  actionStyle,
135
155
  contentType,
136
156
  containerRef,
@@ -146,8 +166,8 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
146
166
  render() {
147
167
  return createVNode("div", {
148
168
  "ref": "containerRef",
149
- "class": this.ns.b(),
150
- "style": this.containerStyle
169
+ "style": this.containerStyle,
170
+ "class": [this.ns.b(), this.ns.m(this.theme), this.ns.is("show-ai", this.isShow)]
151
171
  }, [createVNode("div", {
152
172
  "class": this.ns.e("content"),
153
173
  "style": this.contentStyle
@@ -158,36 +178,31 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
158
178
  }, [AIIcon])]), createVNode("div", {
159
179
  "class": this.ns.em("content", "textarea")
160
180
  }, [this.isLoading && createVNode("div", {
161
- "class": "el-loading-mask",
162
- "style": ""
181
+ "class": this.ns.e("loading")
163
182
  }, [createVNode("div", {
164
- "class": "el-loading-spinner"
165
- }, [createVNode("svg", {
166
- "class": "circular",
167
- "viewBox": "0 0 50 50"
168
- }, [createVNode("circle", {
169
- "class": "path",
170
- "cx": "25",
171
- "cy": "25",
172
- "r": "20",
173
- "fill": "none"
174
- }, null)])])]), withDirectives(createVNode("textarea", {
183
+ "class": this.ns.em("loading", "dot")
184
+ }, null), createVNode("div", {
185
+ "class": this.ns.em("loading", "dot")
186
+ }, null), createVNode("div", {
187
+ "class": this.ns.em("loading", "dot")
188
+ }, null)]), withDirectives(createVNode("textarea", {
189
+ "ref": "textareaRef",
175
190
  "disabled": this.disabled,
176
191
  "onKeydown": this.onKeydown,
177
192
  "onUpdate:modelValue": ($event) => this.textareaContent = $event
178
- }, null), [[vModelText, this.textareaContent]])]), this.contentType === "USER" && createVNode("div", {
193
+ }, null), [[vModelText, this.textareaContent]])]), createVNode("div", {
179
194
  "class": this.ns.em("content", "suffix")
180
- }, [this.isLoading ? createVNode("div", {
195
+ }, [this.isLoading && createVNode("div", {
181
196
  "class": this.ns.em("content", "stop-icon"),
182
197
  "onClick": () => this.stopQuestion()
183
- }, [StopIcon, createVNode("span", null, [ibiz.i18n.t("util.inlineAiUtil.stopEdit")])]) : createVNode("div", {
198
+ }, [StopIcon, createVNode("span", null, [ibiz.i18n.t("util.inlineAiUtil.stopEdit")])]), !this.disabled && createVNode("div", {
184
199
  "class": this.ns.em("content", "sand-icon"),
185
200
  "onClick": () => this.sendQuestion(this.textareaContent)
186
- }, [SendIcon])])]), this.contentType === "ASSISTANT" && createVNode("div", {
187
- "class": this.ns.e("footer")
201
+ }, [SendIcon])])]), createVNode("div", {
202
+ "class": [this.ns.e("footer"), this.ns.is("show", this.isShow)]
188
203
  }, [ibiz.i18n.t("util.inlineAiUtil.info")]), createVNode("div", {
189
204
  "ref": "actionsRef",
190
- "class": [this.ns.e("actions"), this.ns.is("show", this.contentType === "ASSISTANT")],
205
+ "class": [this.ns.e("actions"), this.ns.is("show", this.isShow)],
191
206
  "style": this.actionStyle
192
207
  }, [this.actions.map((action) => {
193
208
  if (action.itemType === "divider")
@@ -56,7 +56,7 @@ const IBizFormItemContainer = /* @__PURE__ */ vue.defineComponent({
56
56
  }, null);
57
57
  }
58
58
  };
59
- const renderInputTip = () => {
59
+ const renderTipsIcon = () => {
60
60
  return vue.createVNode(vue.resolveComponent("el-tooltip"), {
61
61
  "effect": "light",
62
62
  "visible": visible.value,
@@ -66,16 +66,42 @@ const IBizFormItemContainer = /* @__PURE__ */ vue.defineComponent({
66
66
  "placement": labelPos === "RIGHT" ? "right" : "left"
67
67
  }, {
68
68
  default: () => {
69
- return vue.createVNode("div", {
70
- "class": [ns.em("label", "content"), ns.is("tooltip", enableInputTip)]
71
- }, [enableInputTip && ibiz.config.form.showTipsIcon && vue.createVNode("ion-icon", {
69
+ return vue.createVNode("ion-icon", {
72
70
  "name": "bulb-outline",
73
71
  "class": ns.em("label", "icon")
74
- }, null), sysImage && vue.createVNode(vue3Util.IBizIcon, {
72
+ }, null);
73
+ },
74
+ content: () => {
75
+ return vue.createVNode("div", {
76
+ "class": ns.em("popper", "content")
77
+ }, [vue.createVNode("div", {
78
+ "class": ns.em("popper", "tooltip")
79
+ }, [renderTipContent()]), c.state.inputTipUrl && vue.createVNode("a", {
80
+ "target": "_blank",
81
+ "href": c.state.inputTipUrl,
82
+ "title": ibiz.i18n.t("component.formItemContainer.more")
83
+ }, [ibiz.i18n.t("component.formItemContainer.more")])]);
84
+ }
85
+ });
86
+ };
87
+ const renderLabelWithoutTips = () => {
88
+ return vue.createVNode(vue.resolveComponent("el-tooltip"), {
89
+ "effect": "light",
90
+ "visible": visible.value,
91
+ "onUpdate:visible": ($event) => visible.value = $event,
92
+ "popper-class": [ns.e("popper"), ns.is(ibiz.config.tooltiprendermode.toLowerCase(), true)],
93
+ "disabled": !enableInputTip,
94
+ "placement": labelPos === "RIGHT" ? "right" : "left"
95
+ }, {
96
+ default: () => {
97
+ return vue.createVNode("div", {
98
+ "class": [ns.em("label", "content"), ns.is("tooltip", enableInputTip)]
99
+ }, [sysImage && vue.createVNode(vue3Util.IBizIcon, {
75
100
  "class": ns.em("label", "icon"),
76
101
  "icon": sysImage
77
102
  }, null), vue.createVNode("div", {
78
- "class": ns.em("label", "text")
103
+ "class": ns.em("label", "text"),
104
+ "title": enableInputTip ? void 0 : core.showTitle(c.labelCaption)
79
105
  }, [c.labelCaption])]);
80
106
  },
81
107
  content: () => {
@@ -92,10 +118,18 @@ const IBizFormItemContainer = /* @__PURE__ */ vue.defineComponent({
92
118
  });
93
119
  };
94
120
  const renderLabel = () => {
121
+ const showTipsIcon = enableInputTip && ibiz.config.form.showTipsIcon;
95
122
  return vue.createVNode("div", {
96
- "title": enableInputTip ? void 0 : core.showTitle(c.labelCaption),
97
123
  "class": [ns.e("label"), ...c.labelClass || []]
98
- }, [renderInputTip()]);
124
+ }, [showTipsIcon && vue.createVNode("div", {
125
+ "class": [ns.em("label", "content"), ns.is("tooltip", enableInputTip)]
126
+ }, [renderTipsIcon(), sysImage && vue.createVNode(vue3Util.IBizIcon, {
127
+ "class": ns.em("label", "icon"),
128
+ "icon": sysImage
129
+ }, null), vue.createVNode("div", {
130
+ "class": ns.em("label", "text"),
131
+ "title": core.showTitle(c.labelCaption)
132
+ }, [c.labelCaption])]), !showTipsIcon && renderLabelWithoutTips()]);
99
133
  };
100
134
  return {
101
135
  ns,