@opentiny/vue-renderless 3.28.2 → 3.30.0

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 (64) hide show
  1. package/alert/vue.js +4 -1
  2. package/anchor/index.js +11 -1
  3. package/anchor/vue.js +2 -2
  4. package/base-select/index.js +6 -3
  5. package/base-select/vue.js +1 -1
  6. package/calendar-view/index.js +44 -2
  7. package/calendar-view/vue.js +6 -0
  8. package/date-range/index.js +1 -1
  9. package/dialog-box/vue.js +4 -1
  10. package/dialog-select/index.js +1 -1
  11. package/drawer/index.js +13 -1
  12. package/drawer/vue.js +13 -3
  13. package/fluent-editor/index.js +142 -10
  14. package/fluent-editor/vue.js +30 -8
  15. package/form-item/index.js +1 -1
  16. package/form-item/vue.js +11 -1
  17. package/grid-select/index.js +3 -3
  18. package/guide/index.js +17 -11
  19. package/guide/vue.js +2 -1
  20. package/input/vue.js +3 -2
  21. package/modal/index.js +11 -11
  22. package/modal/vue.js +3 -0
  23. package/notify/vue.js +4 -1
  24. package/package.json +3 -3
  25. package/picker/vue.js +3 -2
  26. package/qr-code/vue.js +3 -1
  27. package/rate/index.js +5 -4
  28. package/rate/vue.js +1 -1
  29. package/rich-text/index.js +91 -2
  30. package/rich-text/vue.js +11 -2
  31. package/search/vue.js +6 -1
  32. package/select/index.js +11 -3
  33. package/select/vue.js +5 -4
  34. package/statistic/index.js +48 -1
  35. package/statistic/vue.js +31 -11
  36. package/tabs-mf/index.js +10 -2
  37. package/tag-group/index.js +3 -0
  38. package/tag-input/index.js +91 -0
  39. package/tag-input/vue.js +72 -0
  40. package/time/index.js +22 -0
  41. package/time/vue.js +14 -2
  42. package/time-spinner/index.js +2 -2
  43. package/tree-select/index.js +49 -14
  44. package/types/action-menu.type.d.ts +4 -0
  45. package/types/alert.type.d.ts +2 -0
  46. package/types/anchor.type.d.ts +1 -1
  47. package/types/button-group.type.d.ts +5 -0
  48. package/types/date-picker.type.d.ts +1 -1
  49. package/types/dialog-box.type.d.ts +2 -0
  50. package/types/drawer.type.d.ts +7 -1
  51. package/types/{dropdown-item.type-b3ced3ce.d.ts → dropdown-item.type-f83b014f.d.ts} +1 -1
  52. package/types/dropdown-item.type.d.ts +1 -1
  53. package/types/dropdown-menu.type.d.ts +1 -1
  54. package/types/form-item.type.d.ts +1 -1
  55. package/types/{form.type-a54e1c06.d.ts → form.type-e0db2f7c.d.ts} +9 -0
  56. package/types/form.type.d.ts +1 -1
  57. package/types/modal.type.d.ts +2 -0
  58. package/types/popeditor.type.d.ts +2 -2
  59. package/types/rate.type.d.ts +5 -2
  60. package/types/search.type.d.ts +1 -0
  61. package/types/statistic.type.d.ts +17 -1
  62. package/types/tag-input.type.d.ts +113 -0
  63. package/types/tree-menu.type.d.ts +1 -1
  64. package/user/index.js +5 -5
package/alert/vue.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  watchAutoHide,
10
10
  handlerTargetNode
11
11
  } from "./index";
12
+ import { nanoid } from "@opentiny/utils";
12
13
  const api = ["handleClose", "state", "handleHeaderClick"];
13
14
  const initState = ({ api: api2, computed, constants, reactive }) => {
14
15
  return reactive({
@@ -21,7 +22,9 @@ const initState = ({ api: api2, computed, constants, reactive }) => {
21
22
  getIcon: computed(() => api2.computedGetIcon()),
22
23
  getTitle: computed(() => api2.computedGetTitle()),
23
24
  alertClass: computed(() => api2.computedClass()),
24
- alertStyle: computed(() => api2.computedStyle())
25
+ alertStyle: computed(() => api2.computedStyle()),
26
+ titleId: `tiny-alert-title-${nanoid.api.nanoid(8)}`,
27
+ contentId: `tiny-alert-description-${nanoid.api.nanoid(8)}`
25
28
  });
26
29
  };
27
30
  const initApi = ({ api: api2, state, constants, props, designConfig, t, emit, vm, parent, nextTick, mode }) => {
package/anchor/index.js CHANGED
@@ -160,11 +160,21 @@ const onItersectionObserver = ({ state, props, api, vm, emit }) => () => {
160
160
  );
161
161
  addObserver({ props, state });
162
162
  };
163
- const linkClick = ({ state, vm, emit, props, api }) => (e, item) => {
163
+ const linkClick = ({
164
+ state,
165
+ vm,
166
+ emit,
167
+ props,
168
+ api,
169
+ framework
170
+ }) => (e, item) => {
164
171
  state.isScroll = true;
165
172
  const { link, title } = item;
166
173
  const emitLink = { link, title };
167
174
  emit("linkClick", e, emitLink);
175
+ if (framework === "vue2" || framework === "vue2.7") {
176
+ emit("link-click", e, emitLink);
177
+ }
168
178
  const isChangeHash = setCurrentHash({ state });
169
179
  const { scrollContainer } = state;
170
180
  state.currentLink = link;
package/anchor/vue.js CHANGED
@@ -19,7 +19,7 @@ const api = [
19
19
  "setScrollContainer",
20
20
  "getCurrentAnchor"
21
21
  ];
22
- const renderless = (props, { onMounted, onUnmounted, onUpdated, reactive, watch }, { vm, emit, nextTick }) => {
22
+ const renderless = (props, { onMounted, onUnmounted, onUpdated, reactive, watch }, { vm, emit, nextTick, framework }) => {
23
23
  const api2 = {};
24
24
  const state = reactive({
25
25
  currentLink: "",
@@ -38,7 +38,7 @@ const renderless = (props, { onMounted, onUnmounted, onUpdated, reactive, watch
38
38
  updated: updated({ api: api2 }),
39
39
  unmounted: unmounted({ state, api: api2 }),
40
40
  getContainer: getContainer({ props }),
41
- linkClick: linkClick({ state, vm, emit, props, api: api2 }),
41
+ linkClick: linkClick({ state, vm, emit, props, api: api2, framework }),
42
42
  onItersectionObserver: onItersectionObserver({ state, props, api: api2, vm, emit }),
43
43
  setScrollContainer: setScrollContainer({ state, api: api2 }),
44
44
  getCurrentAnchor: getCurrentAnchor({ vm, state, emit }),
@@ -1214,10 +1214,9 @@ const computedCurrentSizeMap = ({ state, designConfig }) => () => {
1214
1214
  const sizeMap = ((_a = designConfig == null ? void 0 : designConfig.state) == null ? void 0 : _a.sizeMap) || defaultSizeMap;
1215
1215
  return sizeMap[state.selectSize || "default"];
1216
1216
  };
1217
- const mounted = ({ api, parent, state, props, vm, designConfig }) => () => {
1217
+ const mounted = ({ api, parent, state, props, vm, designConfig, nextTick }) => () => {
1218
1218
  const parentEl = parent.$el;
1219
1219
  const inputEl = parentEl.querySelector('input[data-tag="tiny-input-inner"]');
1220
- const inputClientRect = inputEl && inputEl.getBoundingClientRect() || {};
1221
1220
  if (inputEl === document.activeElement) {
1222
1221
  document.activeElement.blur();
1223
1222
  }
@@ -1229,10 +1228,14 @@ const mounted = ({ api, parent, state, props, vm, designConfig }) => () => {
1229
1228
  if (vm.$refs.tags) {
1230
1229
  addResizeListener(vm.$refs.tags, api.resetInputHeight);
1231
1230
  }
1231
+ nextTick(() => {
1232
+ if (inputEl) {
1233
+ state.inputWidth = inputEl.offsetWidth || 0;
1234
+ }
1235
+ });
1232
1236
  if (props.remote && props.multiple) {
1233
1237
  api.resetInputHeight();
1234
1238
  }
1235
- state.inputWidth = inputClientRect.width;
1236
1239
  api.initQuery({ init: true }).then(() => {
1237
1240
  api.setSelected(true);
1238
1241
  if (props.modelValue && props.initLabel) {
@@ -472,7 +472,7 @@ const addApi = ({
472
472
  debouncRquest: debouncRquest({ api: api2, state, props }),
473
473
  defaultOnQueryChange: defaultOnQueryChange({ props, state, constants, api: api2, nextTick, vm }),
474
474
  queryChange: queryChange({ props, state, constants, api: api2, nextTick, vm }),
475
- mounted: mounted({ api: api2, parent, state, props, vm, designConfig }),
475
+ mounted: mounted({ api: api2, parent, state, props, vm, designConfig, nextTick }),
476
476
  unMount: unMount({ api: api2, parent, vm, state }),
477
477
  watchOptimizeOpts: watchOptimizeOpts({ props, state }),
478
478
  handleDropdownClick: handleDropdownClick({ props, vm, state, emit }),
@@ -59,8 +59,48 @@ const isSelectedDate = ({ state }) => (day) => {
59
59
  const getDayBgColor = ({ props }) => (day) => {
60
60
  const date = day.year + "-" + day.month + "-" + day.value;
61
61
  const isFunction = props.setDayBgColor instanceof Function;
62
- const bgColor = isFunction ? props.setDayBgColor(date) : "white";
63
- return bgColor;
62
+ if (isFunction) {
63
+ const result = props.setDayBgColor(date);
64
+ if (typeof result === "object") {
65
+ return result;
66
+ }
67
+ if (typeof result === "string" && (result.startsWith("#") || result.startsWith("rgb"))) {
68
+ return { backgroundColor: result };
69
+ }
70
+ return result;
71
+ }
72
+ return "white";
73
+ };
74
+ const isColorValue = (value) => {
75
+ if (typeof value !== "string")
76
+ return false;
77
+ if (value.startsWith("#"))
78
+ return true;
79
+ if (value.startsWith("rgb"))
80
+ return true;
81
+ return false;
82
+ };
83
+ const getDayBgRawValue = ({ props, day }) => {
84
+ const date = day.year + "-" + day.month + "-" + day.value;
85
+ const isFunction = props.setDayBgColor instanceof Function;
86
+ if (isFunction) {
87
+ return props.setDayBgColor(date);
88
+ }
89
+ return "";
90
+ };
91
+ const getDayBgClass = ({ props }) => (day) => {
92
+ const result = getDayBgRawValue({ props, day });
93
+ if (typeof result === "string" && !isColorValue(result) && result) {
94
+ return "bg-" + result;
95
+ }
96
+ return "";
97
+ };
98
+ const getDayBgStyle = ({ props }) => (day) => {
99
+ const result = getDayBgRawValue({ props, day });
100
+ if (isColorValue(result)) {
101
+ return { backgroundColor: result };
102
+ }
103
+ return {};
64
104
  };
65
105
  const parseDate = (time) => {
66
106
  let date = {};
@@ -642,7 +682,9 @@ export {
642
682
  getCurWeekEvent,
643
683
  getDatesOfNextWeek,
644
684
  getDatesOfPreviousWeek,
685
+ getDayBgClass,
645
686
  getDayBgColor,
687
+ getDayBgStyle,
646
688
  getEventByDate,
647
689
  getEventByMonth,
648
690
  getEventByTime,
@@ -25,6 +25,8 @@ import {
25
25
  isSelectedDate,
26
26
  isStartOrEndDay,
27
27
  getDayBgColor,
28
+ getDayBgStyle,
29
+ getDayBgClass,
28
30
  isShowNewSchedule,
29
31
  genDayTimes,
30
32
  isShowMark,
@@ -62,6 +64,8 @@ const api = [
62
64
  "isSelectedDate",
63
65
  "isStartOrEndDay",
64
66
  "getDayBgColor",
67
+ "getDayBgStyle",
68
+ "getDayBgClass",
65
69
  "isShowNewSchedule",
66
70
  "isShowMark",
67
71
  "handleCascaderChange",
@@ -281,6 +285,8 @@ const initApi = ({ vm, api: api2, state, t, props, emit, nextTick }) => {
281
285
  isSelectedDate: isSelectedDate({ state }),
282
286
  isStartOrEndDay: isStartOrEndDay({ state }),
283
287
  getDayBgColor: getDayBgColor({ props }),
288
+ getDayBgStyle: getDayBgStyle({ props }),
289
+ getDayBgClass: getDayBgClass({ props }),
284
290
  isShowNewSchedule: isShowNewSchedule({ props }),
285
291
  genDayTimes: genDayTimes({ props }),
286
292
  isShowMark: isShowMark({ props }),
@@ -139,7 +139,7 @@ const handleClear = ({ emit, state }) => () => {
139
139
  state.rightDate = nextMonth1(state.leftDate);
140
140
  state.rangeState.selecting = false;
141
141
  state.rangeState.endDate = null;
142
- emit("pick", []);
142
+ emit("pick", null);
143
143
  };
144
144
  const handleChangeRange = (state, props) => (val) => {
145
145
  if (props.readonly) {
package/dialog-box/vue.js CHANGED
@@ -22,6 +22,7 @@ import {
22
22
  hideScrollbar,
23
23
  toggleFullScreen
24
24
  } from "./index";
25
+ import { nanoid } from "@opentiny/utils";
25
26
  import { usePopup } from "@opentiny/vue-hooks";
26
27
  const api = [
27
28
  "afterEnter",
@@ -61,7 +62,9 @@ const initState = ({
61
62
  style: computed(() => api2.computedStyle()),
62
63
  animationName: computed(() => api2.computedAnimationName()),
63
64
  current,
64
- dragStyle: null
65
+ dragStyle: null,
66
+ titleId: `tiny-dialog-box-title-${nanoid.api.nanoid(8)}`,
67
+ contentId: `tiny-dialog-box-content-${nanoid.api.nanoid(8)}`
65
68
  });
66
69
  return state;
67
70
  };
@@ -439,7 +439,7 @@ const multiGridRadioChange = ({ props, state }) => ({ row, $table }, event) => {
439
439
  }
440
440
  };
441
441
  const watchMulti = ({ api, state, props }) => () => {
442
- state.splitValue = props.multi ? 0.7 : 1;
442
+ state.splitValue = props.multi && props.showSelectedBox ? 0.7 : 1;
443
443
  state.selectedChanged = false;
444
444
  state.selectedDatas = [];
445
445
  state.selectedValues = [];
package/drawer/index.js CHANGED
@@ -28,8 +28,19 @@ const computedHeight = ({
28
28
  const close = ({ api }) => (force = true) => {
29
29
  api.handleClose("close", typeof force === "boolean" ? force : false);
30
30
  };
31
- const watchVisible = ({ state, api }) => (value) => {
31
+ const closed = ({ state, emit }) => () => {
32
+ if (!state.visible) {
33
+ emit("closed");
34
+ }
35
+ };
36
+ const watchVisible = ({ props, parent, api }) => (value) => {
32
37
  value ? api.open() : api.close();
38
+ if (value) {
39
+ const el = parent.$el;
40
+ if (props.appendToBody) {
41
+ document.body.appendChild(el);
42
+ }
43
+ }
33
44
  };
34
45
  const open = ({ state, emit, vm }) => () => {
35
46
  if (!state.visible) {
@@ -146,6 +157,7 @@ export {
146
157
  addDragEvent,
147
158
  addKeydownEvent,
148
159
  close,
160
+ closed,
149
161
  computedHeight,
150
162
  computedWidth,
151
163
  confirm,
package/drawer/vue.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import "../chunk-G2ADBYYC.js";
2
2
  import {
3
3
  close,
4
+ closed,
4
5
  watchVisible,
5
6
  confirm,
6
7
  mousedown,
@@ -18,8 +19,8 @@ import {
18
19
  addKeydownEvent,
19
20
  removeKeydownEvent
20
21
  } from "./index";
21
- const api = ["state", "close", "confirm", "handleClose", "open"];
22
- const renderless = (props, { reactive, watch, onMounted, onBeforeUnmount, computed }, { emit, vm, mode, constants, designConfig }) => {
22
+ const api = ["state", "close", "closed", "confirm", "handleClose", "open"];
23
+ const renderless = (props, { reactive, watch, onMounted, onBeforeUnmount, computed }, { emit, vm, mode, parent, constants, designConfig }) => {
23
24
  const lockScrollClass = constants.SCROLL_LOCK_CLASS(mode);
24
25
  const api2 = {};
25
26
  const state = reactive({
@@ -35,6 +36,7 @@ const renderless = (props, { reactive, watch, onMounted, onBeforeUnmount, comput
35
36
  open: open({ state, emit, vm }),
36
37
  confirm: confirm({ api: api2 }),
37
38
  close: close({ api: api2 }),
39
+ closed: closed({ state, emit }),
38
40
  handleClose: handleClose({ emit, props, state }),
39
41
  mousedown: mousedown({ state, vm }),
40
42
  mousemove: mousemove({ state, props, emit }),
@@ -44,13 +46,17 @@ const renderless = (props, { reactive, watch, onMounted, onBeforeUnmount, comput
44
46
  removeKeydownEvent: removeKeydownEvent({ api: api2 }),
45
47
  addDragEvent: addDragEvent({ api: api2, vm }),
46
48
  removeDragEvent: removeDragEvent({ api: api2, vm }),
47
- watchVisible: watchVisible({ state, api: api2 }),
49
+ watchVisible: watchVisible({ props, parent, api: api2 }),
48
50
  showScrollbar: showScrollbar(lockScrollClass),
49
51
  hideScrollbar: hideScrollbar(lockScrollClass),
50
52
  computedWidth: computedWidth({ state, designConfig, props, constants }),
51
53
  computedHeight: computedHeight({ state, designConfig, props, constants })
52
54
  });
53
55
  onMounted(() => {
56
+ const el = parent.$el;
57
+ if (props.appendToBody && el && el.parentNode !== document.body) {
58
+ document.body.appendChild(el);
59
+ }
54
60
  props.dragable && api2.addDragEvent();
55
61
  api2.addKeydownEvent();
56
62
  if (props.lockScroll && props.visible) {
@@ -61,6 +67,10 @@ const renderless = (props, { reactive, watch, onMounted, onBeforeUnmount, comput
61
67
  props.dragable && api2.removeDragEvent();
62
68
  api2.removeKeydownEvent();
63
69
  props.lockScroll && api2.hideScrollbar();
70
+ const el = parent.$el;
71
+ if (props.appendToBody && el && el.parentNode) {
72
+ el.parentNode.removeChild(el);
73
+ }
64
74
  });
65
75
  watch(() => props.visible, api2.watchVisible, { immediate: true });
66
76
  watch(
@@ -1,10 +1,21 @@
1
- import "../chunk-G2ADBYYC.js";
1
+ import {
2
+ __spreadValues
3
+ } from "../chunk-G2ADBYYC.js";
2
4
  import { extend } from "@opentiny/utils";
3
5
  import { isNull } from "@opentiny/utils";
4
6
  import { xss } from "@opentiny/utils";
5
7
  import { set } from "../chart-core/deps/utils";
6
8
  import { on, off } from "@opentiny/utils";
7
9
  import { PopupManager } from "@opentiny/utils";
10
+ const isSafeLinkUrl = (url) => /^(https?:|mailto:|tel:|\/|#)/i.test((url || "").trim());
11
+ const openLink = (url, target = "_blank") => {
12
+ if (target === "_blank") {
13
+ const popup = window.open(url, "_blank", "noopener,noreferrer");
14
+ popup && (popup.opener = null);
15
+ return;
16
+ }
17
+ window.location.assign(url);
18
+ };
8
19
  const init = ({
9
20
  api,
10
21
  emit,
@@ -18,12 +29,23 @@ const init = ({
18
29
  useBreakpoint,
19
30
  simpleToolbar
20
31
  }) => () => {
21
- var _a;
32
+ var _a, _b, _c;
22
33
  UploaderDfls.enableMultiUpload = { file: true, image: true };
23
34
  UploaderDfls.handler = api.uploaderDflsHandler;
24
35
  UploaderDfls.imagePasteFailCallback = props.imagePasteFailCallback;
25
36
  defaultOptions.modules.toolbar.handlers = api.handlers();
26
37
  state.innerOptions = extend(true, {}, defaultOptions, props.globalOptions, props.options);
38
+ const toolbarOpt = (_b = (_a = state.innerOptions) == null ? void 0 : _a.modules) == null ? void 0 : _b.toolbar;
39
+ const defaultHandlers = api.handlers();
40
+ if (Array.isArray(toolbarOpt)) {
41
+ state.innerOptions.modules.toolbar = {
42
+ container: toolbarOpt,
43
+ handlers: defaultHandlers
44
+ };
45
+ } else if (toolbarOpt && typeof toolbarOpt === "object") {
46
+ const userHandlers = toolbarOpt.handlers || {};
47
+ state.innerOptions.modules.toolbar.handlers = __spreadValues(__spreadValues({}, defaultHandlers), userHandlers);
48
+ }
27
49
  if (props.imageUpload) {
28
50
  state.innerOptions.imageUpload = props.imageUpload;
29
51
  } else {
@@ -43,10 +65,12 @@ const init = ({
43
65
  if (current.value === "default") {
44
66
  state.innerOptions.modules.toolbar = simpleToolbar;
45
67
  }
46
- (_a = props.beforeEditorInit) == null ? void 0 : _a.call(props, FluentEditor);
68
+ (_c = props.beforeEditorInit) == null ? void 0 : _c.call(props, FluentEditor);
47
69
  const quill = new FluentEditor(vm.$refs.editor, state.innerOptions);
48
70
  quill.emitter.on("file-change", api.fileOperationToSev);
49
71
  state.quill = Object.freeze(quill);
72
+ state.linkClickHandler = api.handleLinkClick;
73
+ on(state.quill.root, "click", state.linkClickHandler);
50
74
  setTimeout(api.setToolbarTitle);
51
75
  let insertTableButton = vm.$el.querySelector(".ql-better-table");
52
76
  const tableModule = state.quill.getModule("better-table");
@@ -188,12 +212,18 @@ const redoHandler = ({ state }) => () => {
188
212
  const lineheightHandler = ({ state, FluentEditor }) => (value) => {
189
213
  state.quill.format("lineheight", value, FluentEditor.sources.USER);
190
214
  };
191
- const fileHandler = ({ api, state }) => () => {
215
+ const fileHandler = ({ api, state, props }) => () => {
216
+ if (props.disabled) {
217
+ return;
218
+ }
192
219
  const option = state.quill.options.uploadOption;
193
220
  const accept = option && option.fileAccept;
194
221
  api.inputFileHandler("file", accept);
195
222
  };
196
- const imageHandler = ({ api, state }) => () => {
223
+ const imageHandler = ({ api, state, props }) => () => {
224
+ if (props.disabled) {
225
+ return;
226
+ }
197
227
  const option = state.quill.options.uploadOption;
198
228
  const accept = option && option.imageAccept;
199
229
  api.inputFileHandler("image", accept);
@@ -220,7 +250,10 @@ const inputFileHandler = ({ state, UploaderDfls }) => (type, accept) => {
220
250
  }
221
251
  fileInput.click();
222
252
  };
223
- const uploaderDflsHandler = ({ api, modules }) => (range, files, fileFlags, rejectFlags) => {
253
+ const uploaderDflsHandler = ({ api, modules, props }) => (range, files, fileFlags, rejectFlags) => {
254
+ if (props.disabled) {
255
+ return;
256
+ }
224
257
  const fileArr = [];
225
258
  const imgArr = [];
226
259
  files.forEach((file, index) => fileFlags[index] ? fileArr.push(file) : imgArr.push(file));
@@ -378,7 +411,15 @@ const handleUploadImage = ({ state, api, FluentEditor, Delta, UploaderDfls }) =>
378
411
  state.promisesData.push({
379
412
  imageEnableMultiUpload
380
413
  });
381
- state.promises.push(api.uploadImageToSev(result));
414
+ const toRead = imageEnableMultiUpload ? files : [file];
415
+ const readFileToBlob = (f) => f.arrayBuffer().then((ab) => new Blob([ab], { type: f.type }));
416
+ const uploadPromise = Promise.all(toRead.map(readFileToBlob)).then((blobs) => {
417
+ result.file = blobs[0];
418
+ result.fileName = file.name;
419
+ result.data.files = blobs;
420
+ api.uploadImageToSev(result);
421
+ });
422
+ state.promises.push(uploadPromise);
382
423
  } else {
383
424
  const promises = files.map((fileItem) => {
384
425
  return new Promise((resolve) => {
@@ -419,7 +460,7 @@ const insertImageToEditor = ({ state, FluentEditor, Delta }) => (range, { data }
419
460
  state.quill.updateContents(newContent, FluentEditor.sources.USER);
420
461
  };
421
462
  const uploadImageToSev = ({ state }) => (event) => {
422
- const { file, hasRejectedImage, callback } = event;
463
+ const { file, fileName, hasRejectedImage, callback } = event;
423
464
  const { files } = event.data;
424
465
  if (hasRejectedImage) {
425
466
  return;
@@ -435,7 +476,7 @@ const uploadImageToSev = ({ state }) => (event) => {
435
476
  return;
436
477
  }
437
478
  let { fd = new FormData(), xhr = new XMLHttpRequest() } = {};
438
- fd.append(name, file, file.name);
479
+ fd.append(name, file, fileName || file.name || "file");
439
480
  options.csrf && fd.append(options.csrf.token, options.csrf.hash);
440
481
  xhr.withCredentials = options.withCredentials !== false;
441
482
  xhr.open(method, url, true);
@@ -458,6 +499,59 @@ const uploadImageToSev = ({ state }) => (event) => {
458
499
  };
459
500
  xhr.send(fd);
460
501
  };
502
+ const alignHandler = ({ state, FluentEditor }) => (value) => {
503
+ var _a, _b, _c, _d;
504
+ const range = state.quill.getSelection(true);
505
+ if (!range) {
506
+ return;
507
+ }
508
+ const betterTableModule = state.quill.getModule("better-table");
509
+ const selectedTds = (_a = betterTableModule == null ? void 0 : betterTableModule.tableSelection) == null ? void 0 : _a.selectedTds;
510
+ if (Array.isArray(selectedTds) && selectedTds.length > 0) {
511
+ const selectedCells = selectedTds.map((tdBlot) => tdBlot == null ? void 0 : tdBlot.domNode).filter(Boolean);
512
+ selectedCells.forEach((cellElement) => {
513
+ const cellBlot = state.quill.scroll.find(cellElement);
514
+ if (!cellBlot)
515
+ return;
516
+ const lines = [];
517
+ const findLines = (blot) => {
518
+ var _a2, _b2;
519
+ if (((_a2 = blot == null ? void 0 : blot.statics) == null ? void 0 : _a2.blotName) === "table-cell-line") {
520
+ lines.push(blot);
521
+ }
522
+ if ((_b2 = blot == null ? void 0 : blot.children) == null ? void 0 : _b2.length) {
523
+ blot.children.forEach((child) => findLines(child));
524
+ }
525
+ };
526
+ findLines(cellBlot);
527
+ lines.forEach((line2) => {
528
+ var _a2;
529
+ try {
530
+ const lineIndex = state.quill.getIndex(line2);
531
+ if (lineIndex !== null && lineIndex >= 0) {
532
+ const lineLength = line2.length();
533
+ if (lineLength > 0) {
534
+ state.quill.formatLine(lineIndex, lineLength, "align", value, FluentEditor.sources.USER);
535
+ }
536
+ }
537
+ } catch (e) {
538
+ try {
539
+ (_a2 = line2 == null ? void 0 : line2.format) == null ? void 0 : _a2.call(line2, "align", value);
540
+ } catch (err) {
541
+ }
542
+ }
543
+ });
544
+ });
545
+ (_c = (_b = betterTableModule == null ? void 0 : betterTableModule.tableSelection) == null ? void 0 : _b.clearSelection) == null ? void 0 : _c.call(_b);
546
+ return;
547
+ }
548
+ const [line] = state.quill.getLine(range.index);
549
+ if (((_d = line == null ? void 0 : line.statics) == null ? void 0 : _d.blotName) === "table-cell-line") {
550
+ state.quill.formatLine(range.index, 1, "align", value, FluentEditor.sources.USER);
551
+ return;
552
+ }
553
+ state.quill.format("align", value, FluentEditor.sources.USER);
554
+ };
461
555
  const handlers = ({ api }) => () => {
462
556
  return {
463
557
  undo: api.undoHandler,
@@ -465,7 +559,8 @@ const handlers = ({ api }) => () => {
465
559
  lineheight: api.lineheightHandler,
466
560
  file: api.fileHandler,
467
561
  image: api.imageHandler,
468
- inputFile: api.inputFileHandler
562
+ inputFile: api.inputFileHandler,
563
+ align: api.alignHandler
469
564
  };
470
565
  };
471
566
  const getFileUploadUrl = ({ service }) => () => {
@@ -566,9 +661,44 @@ const beforeUnmount = ({ state, api, vm }) => () => {
566
661
  api.removeHandleComposition();
567
662
  state.quill.off("selection-change", api.selectionChange);
568
663
  state.quill.off("text-change", api.textChange);
664
+ off(state.quill.root, "click", state.linkClickHandler);
665
+ state.linkClickHandler = null;
569
666
  state.quill = null;
570
667
  delete state.quill;
571
668
  };
669
+ const handleLinkClick = ({ props, state }) => (event) => {
670
+ var _a;
671
+ const anchor = ((_a = event == null ? void 0 : event.target) == null ? void 0 : _a.closest) && event.target.closest("a[href]");
672
+ if (!anchor) {
673
+ return;
674
+ }
675
+ const rawHref = anchor.getAttribute("href") || "";
676
+ const href = xss.filterUrl(rawHref);
677
+ event.preventDefault();
678
+ if (!href || !isSafeLinkUrl(href)) {
679
+ return;
680
+ }
681
+ const payload = {
682
+ url: href,
683
+ rawUrl: rawHref,
684
+ target: anchor.getAttribute("target") || "_blank",
685
+ rel: anchor.getAttribute("rel") || "",
686
+ event,
687
+ quill: state.quill
688
+ };
689
+ const beforeLinkOpen = props.beforeLinkOpen;
690
+ if (typeof beforeLinkOpen !== "function") {
691
+ openLink(payload.url, payload.target);
692
+ return;
693
+ }
694
+ const open = (allow) => allow !== false && openLink(payload.url, payload.target);
695
+ try {
696
+ const result = beforeLinkOpen(payload);
697
+ result && typeof result.then === "function" ? result.then(open).catch(() => {
698
+ }) : open(result);
699
+ } catch (_) {
700
+ }
701
+ };
572
702
  const computePreviewOptions = ({ props, state, constants, api }) => () => {
573
703
  if (props.picPreview && state.previewImgUrl) {
574
704
  let previewOptions = typeof props.picPreview === "boolean" ? constants.PIC_PREVIEW_OPTIONS : props.picPreview;
@@ -661,6 +791,7 @@ const setToolbarTitle = ({ state, t }) => () => {
661
791
  const computeZIndex = ({ constants, props }) => () => props.zIndex === constants.EDITOR_FULLSCREEN_OPTIONS || props.zIndex < 1 ? PopupManager.nextZIndex() : props.zIndex;
662
792
  export {
663
793
  addFullscreenchange,
794
+ alignHandler,
664
795
  beforeUnmount,
665
796
  checkTableISEndElement,
666
797
  computePreviewOptions,
@@ -674,6 +805,7 @@ export {
674
805
  handleCompositionend,
675
806
  handleCompositionstart,
676
807
  handleDblclick,
808
+ handleLinkClick,
677
809
  handleUploadFile,
678
810
  handleUploadImage,
679
811
  handlers,
@@ -36,7 +36,9 @@ import {
36
36
  handleCompositionstart,
37
37
  handleCompositionend,
38
38
  removeHandleComposition,
39
- checkTableISEndElement
39
+ checkTableISEndElement,
40
+ alignHandler,
41
+ handleLinkClick
40
42
  } from "./index";
41
43
  import { defaultOption, iconOption, iconOptionMobileFirst, simpleToolbar } from "./options";
42
44
  const api = ["state", "init", "initContent", "selectionChange", "textChange", "doPreview", "handleDblclick"];
@@ -49,6 +51,7 @@ const initState = ({ api: api2, reactive, computed, props }) => {
49
51
  innerContent: "",
50
52
  fileUploadUrl: props.fileUpload && props.fileUpload.url || "",
51
53
  quill: null,
54
+ linkClickHandler: null,
52
55
  fileInput: null,
53
56
  previewOptions: computed(() => api2.computePreviewOptions()),
54
57
  previewImgUrl: "",
@@ -101,13 +104,19 @@ const initApi = ({ api: api2, state, service, emit, props, nextTick, FluentEdito
101
104
  undoHandler: undoHandler({ state }),
102
105
  redoHandler: redoHandler({ state }),
103
106
  lineheightHandler: lineheightHandler({ state, FluentEditor }),
107
+ alignHandler: alignHandler({ state, FluentEditor }),
104
108
  inputFileHandler: inputFileHandler({ state, UploaderDfls }),
105
109
  insertFileToEditor: insertFileToEditor({ state, FluentEditor, Delta }),
106
110
  insertImageToEditor: insertImageToEditor({ state, FluentEditor, Delta }),
107
111
  uploadImageToSev: uploadImageToSev({ state }),
108
112
  doPreview: doPreview({ props, state, nextTick }),
109
113
  stringToJson: stringToJson({ props }),
110
- setToolbarTips: setToolbarTips({ api: api2, vm, FluentEditor, iconOption: mode === "mobile-first" ? iconOptionMobileFirst : iconOption }),
114
+ setToolbarTips: setToolbarTips({
115
+ api: api2,
116
+ vm,
117
+ FluentEditor,
118
+ iconOption: mode === "mobile-first" ? iconOptionMobileFirst : iconOption
119
+ }),
111
120
  getOuterHTML: getOuterHTML(),
112
121
  setToolbarTitle: setToolbarTitle({ state, t })
113
122
  });
@@ -116,11 +125,23 @@ const mergeApi = (args) => {
116
125
  let { api: api2, state, service, emit, props, vm, i18n, watch, nextTick, useBreakpoint } = args;
117
126
  let { constants, FluentEditor, UploaderDfls, Delta, defaultOptions } = args;
118
127
  Object.assign(api2, {
119
- init: init({ api: api2, emit, props, service, state, FluentEditor, UploaderDfls, defaultOptions, vm, useBreakpoint, simpleToolbar }),
128
+ init: init({
129
+ api: api2,
130
+ emit,
131
+ props,
132
+ service,
133
+ state,
134
+ FluentEditor,
135
+ UploaderDfls,
136
+ defaultOptions,
137
+ vm,
138
+ useBreakpoint,
139
+ simpleToolbar
140
+ }),
120
141
  initContent: initContent({ state, props, api: api2, nextTick }),
121
- fileHandler: fileHandler({ api: api2, state }),
122
- imageHandler: imageHandler({ api: api2, state }),
123
- uploaderDflsHandler: uploaderDflsHandler({ api: api2, modules: defaultOptions.modules }),
142
+ fileHandler: fileHandler({ api: api2, state, props }),
143
+ imageHandler: imageHandler({ api: api2, state, props }),
144
+ uploaderDflsHandler: uploaderDflsHandler({ api: api2, modules: defaultOptions.modules, props }),
124
145
  handleUploadFile: handleUploadFile({ api: api2, UploaderDfls }),
125
146
  handleUploadImage: handleUploadImage({ state, api: api2, FluentEditor, Delta, UploaderDfls }),
126
147
  handlers: handlers({ api: api2 }),
@@ -136,7 +157,8 @@ const mergeApi = (args) => {
136
157
  handleComposition: handleComposition({ state, api: api2 }),
137
158
  handleCompositionstart: handleCompositionstart({ state }),
138
159
  handleCompositionend: handleCompositionend({ state }),
139
- removeHandleComposition: removeHandleComposition({ state, api: api2 })
160
+ removeHandleComposition: removeHandleComposition({ state, api: api2 }),
161
+ handleLinkClick: handleLinkClick({ props, state })
140
162
  });
141
163
  };
142
164
  const initWatch = ({ watch, state, api: api2, props, vm }) => {
@@ -170,7 +192,7 @@ const initWatch = ({ watch, state, api: api2, props, vm }) => {
170
192
  const renderless = (props, { reactive, watch, onMounted, onBeforeUnmount, computed }, { service, emit, i18n, constants, nextTick, vm, t, useBreakpoint, mode }, { FluentEditor }) => {
171
193
  const api2 = {};
172
194
  const { DEFAULTS: UploaderDfls } = FluentEditor.imports["modules/uploader"];
173
- const Delta = FluentEditor.imports["delta"];
195
+ const Delta = FluentEditor.imports.delta;
174
196
  const state = initState({ reactive, computed, api: api2, props });
175
197
  const defaultOptions = defaultOption({ FluentEditor, state, mentionObj: props.mentionObj });
176
198
  initApi({ api: api2, state, service, emit, props, nextTick, FluentEditor, UploaderDfls, Delta, vm, t, mode });
@@ -268,7 +268,7 @@ const getFilteredRule = (api) => (trigger) => {
268
268
  }).map((rule) => merge({}, rule));
269
269
  };
270
270
  const onFieldBlur = (api) => () => {
271
- api.validate("blur");
271
+ api.validateOrigin("blur");
272
272
  };
273
273
  const onFieldChange = ({ api, state }) => () => {
274
274
  if (state.validateDisabled) {