snail.vue 1.0.48 → 1.0.49

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/snail.vue.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //@ sourceURL=/snail.vue.js
2
- import { defineComponent, createElementBlock, openBlock, normalizeClass, renderSlot, createTextVNode, shallowRef, computed, normalizeStyle, createElementVNode, toDisplayString, Fragment, renderList, unref, mergeModels, useModel, createCommentVNode, createBlock, nextTick, withDirectives, vModelText, createVNode, createApp, Transition, withCtx, normalizeProps, guardReactiveProps, watch, ref, onErrorCaptured, resolveDynamicComponent, mergeProps, createSlots, onMounted, withModifiers, isRef, getCurrentInstance, useTemplateRef, resolveComponent, onBeforeUnmount, getCurrentScope, onScopeDispose } from 'vue';
2
+ import { defineComponent, createElementBlock, openBlock, normalizeClass, renderSlot, createTextVNode, shallowRef, normalizeStyle, createElementVNode, toDisplayString, Fragment, renderList, unref, mergeModels, useModel, computed, createCommentVNode, createBlock, nextTick, withDirectives, vModelText, createVNode, createApp, Transition, withCtx, normalizeProps, guardReactiveProps, watch, ref, onErrorCaptured, resolveDynamicComponent, mergeProps, createSlots, onMounted, withModifiers, isRef, getCurrentInstance, useTemplateRef, resolveComponent, onBeforeUnmount, getCurrentScope, onScopeDispose } from 'vue';
3
3
  import { throwError, isArrayNotEmpty, isStringNotEmpty, isArray, newId, mustFunction, useScope, removeFromArray, mustObject, throwIfFalse, isObject, isNumberNotNaN, mountScope, useScopes, isPromise, wait, script, delay, useTimer, defer, useAsyncScope, useHook, hasAny, throwIfTrue, isFunction, onMountScope } from 'snail.core';
4
4
  import { link, css, useObserver, useAnimation } from 'snail.view';
5
5
 
@@ -27,8 +27,8 @@ var addLink = href => setTimeout(link.register, 0, href);
27
27
 
28
28
  addLink("/styles/snail.vue.vue.css");
29
29
 
30
- function getSvgDraw(options) {
31
- switch (options.type) {
30
+ function getSvgDraw(iconType, draw) {
31
+ switch (iconType) {
32
32
  case "success":
33
33
  return ["M 102.272 613.285 a 48.9258 48.9258 0 0 1 -1.34967 -62.8444 l 26.0656 -31.2113 a 50.6129 50.6129 0 0 1 62.6756 -11.2192 l 199.583 121.218 c 19.4859 11.8097 49.0102 8.26677 65.9655 -8.01371 l 540.714 -519.625 a 40.3216 40.3216 0 0 1 57.9518 1.6871 l 37.9597 43.3583 a 47.5762 47.5762 0 0 1 -0.843545 62.4226 L 452.766 920.675 a 38.4658 38.4658 0 0 1 -56.8553 1.18097 L 102.272 613.285 Z"];
34
34
  case "error":
@@ -47,19 +47,23 @@ function getSvgDraw(options) {
47
47
  return ["M 780.8 366.933 c 34.1333 -34.1333 34.1333 -93.8667 0 -128 c -38.4 -34.1333 -93.8667 -34.1333 -132.267 0 l -68.2667 68.2667 l 132.267 128 l 68.2667 -68.2667 Z M 541.867 349.867 l -277.333 277.333 L 213.333 806.4 l 179.2 -51.2 l 281.6 -277.333 Z M 469.333 768 h 341.333 v 42.6667 h -341.333 Z"];
48
48
  case "arrow":
49
49
  return ["M651.3 514.2c0 8.2-3.1 16.4-9.4 22.6L426.4 752.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L574 514.2 381.1 321.4c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l215.5 215.5c6.2 6.3 9.4 14.5 9.4 22.6z"];
50
+ case "plus":
51
+ return ["M 768 469.333 h -213.333 V 256 c 0 -25.6 -17.0667 -42.6667 -42.6667 -42.6667 s -42.6667 17.0667 -42.6667 42.6667 v 213.333 H 256 c -25.6 0 -42.6667 17.0667 -42.6667 42.6667 s 17.0667 42.6667 42.6667 42.6667 h 213.333 v 213.333 c 0 25.6 17.0667 42.6667 42.6667 42.6667 s 42.6667 -17.0667 42.6667 -42.6667 v -213.333 h 213.333 c 25.6 0 42.6667 -17.0667 42.6667 -42.6667 s -17.0667 -42.6667 -42.6667 -42.6667 Z"];
52
+ case "subtract":
53
+ return ["M768 554.666667H256c-25.6 0-42.666667-17.066667-42.666667-42.666667s17.066667-42.666667 42.666667-42.666667h512c25.6 0 42.666667 17.066667 42.666667 42.666667s-17.066667 42.666667-42.666667 42.666667z"];
50
54
  case "grip":
51
55
  return ["M 384 256 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 384 426.667 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 384 597.333 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 384 768 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 640 256 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 640 426.667 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 640 597.333 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z", "M 640 768 m -42.6667 0 a 42.6667 42.6667 0 1 0 85.3333 0 a 42.6667 42.6667 0 1 0 -85.3333 0 Z"];
52
56
  case "custom":
53
- return isArrayNotEmpty(options.draw) ? options.draw : isStringNotEmpty(options.draw) ? [options.draw] : throwError("options.draw must be a non-empty string or string array");
57
+ return isArrayNotEmpty(draw) ? draw : isStringNotEmpty(draw) ? [draw] : throwError("options.draw must be a non-empty string or string array");
54
58
  default:
55
- throwError(`not support icon type: ${options.type}.`);
59
+ throwError(`not support icon type: ${iconType}.`);
56
60
  break;
57
61
  }
58
62
  }
59
63
 
60
64
  const _hoisted_1$f = ["width", "height"];
61
65
  const _hoisted_2$a = ["textContent"];
62
- const _hoisted_3$6 = ["d", "fill"];
66
+ const _hoisted_3$7 = ["fill", "stroke", "stroke-width", "d"];
63
67
  var _sfc_main$s = defineComponent({
64
68
  ...{
65
69
  name: "Icon",
@@ -72,36 +76,31 @@ var _sfc_main$s = defineComponent({
72
76
  color: {},
73
77
  hoverColor: {},
74
78
  size: {},
79
+ stroke: {},
80
+ strokeWidth: {},
75
81
  draw: {},
76
82
  rotate: {}
77
83
  },
78
84
  setup(__props) {
79
- const props = __props;
80
- const paths = getSvgDraw(props || {});
81
- const colorRef = shallowRef(props.color);
82
- const styleRef = computed(() => props.rotate ? `transform: rotate(${props.rotate}deg);` : "");
83
- function onMouseEnter() {
84
- colorRef.value = props.hoverColor || props.color;
85
- }
86
- function onMouseLeave() {
87
- colorRef.value = props.color;
88
- }
85
+ const isMouseEnterRef = shallowRef(false);
89
86
  return (_ctx, _cache) => {
90
87
  return openBlock(), createElementBlock("svg", {
91
88
  class: normalizeClass(["snail-icon", _ctx.type]),
92
89
  viewBox: "0 0 1024 1024",
93
- width: props.size || 24,
94
- height: props.size || 24,
95
- style: normalizeStyle(styleRef.value),
96
- onMouseenter: onMouseEnter,
97
- onMouseleave: onMouseLeave
90
+ style: normalizeStyle(_ctx.rotate ? `transform: rotate(${_ctx.rotate}deg);` : ""),
91
+ width: _ctx.size || 24,
92
+ height: _ctx.size || 24,
93
+ onMouseenter: _cache[0] || (_cache[0] = $event => isMouseEnterRef.value = true),
94
+ onMouseleave: _cache[1] || (_cache[1] = $event => isMouseEnterRef.value = false)
98
95
  }, [createElementVNode("title", {
99
- textContent: toDisplayString(props.title || "")
100
- }, null, 8, _hoisted_2$a), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(paths), draw => {
96
+ textContent: toDisplayString(_ctx.title || "")
97
+ }, null, 8, _hoisted_2$a), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(getSvgDraw)(_ctx.type, _ctx.draw), draw => {
101
98
  return openBlock(), createElementBlock("path", {
102
- d: draw,
103
- fill: colorRef.value
104
- }, null, 8, _hoisted_3$6);
99
+ fill: isMouseEnterRef.value ? _ctx.hoverColor || _ctx.color : _ctx.color,
100
+ stroke: _ctx.stroke,
101
+ "stroke-width": _ctx.strokeWidth,
102
+ d: draw
103
+ }, null, 8, _hoisted_3$7);
105
104
  }), 256))], 46, _hoisted_1$f);
106
105
  };
107
106
  }
@@ -109,7 +108,7 @@ var _sfc_main$s = defineComponent({
109
108
 
110
109
  const _hoisted_1$e = ["onClick"];
111
110
  const _hoisted_2$9 = ["type", "checked"];
112
- const _hoisted_3$5 = ["textContent"];
111
+ const _hoisted_3$6 = ["textContent"];
113
112
  const _hoisted_4$4 = ["textContent"];
114
113
  var _sfc_main$r = defineComponent({
115
114
  ...{
@@ -191,7 +190,7 @@ var _sfc_main$r = defineComponent({
191
190
  key: 2,
192
191
  class: "item-text",
193
192
  textContent: toDisplayString(item.text)
194
- }, null, 8, _hoisted_3$5)) : createCommentVNode("", true), item.description ? (openBlock(), createElementBlock("span", {
193
+ }, null, 8, _hoisted_3$6)) : createCommentVNode("", true), item.description ? (openBlock(), createElementBlock("span", {
195
194
  key: 3,
196
195
  class: "item-des",
197
196
  textContent: toDisplayString(item.description)
@@ -480,23 +479,11 @@ function checkFollow(options) {
480
479
  function calcFollowX(options, target, width) {
481
480
  const space = isNumberNotNaN(options.spaceX) ? options.spaceX : 0;
482
481
  const spaceClient = isNumberNotNaN(options.spaceClient) ? options.spaceClient : 0;
483
- if (target.left < spaceClient || target.right + spaceClient > window.innerWidth) {
484
- return {
485
- strategy: void 0,
486
- start: -width
487
- };
488
- }
489
482
  return electPosition(getFollowStrategy(options.followX) || ["start", "end", "after", "before", "center", "ratio"], target.left, target.right, width, window.innerWidth, space, spaceClient);
490
483
  }
491
484
  function calcFollowY(options, target, height) {
492
485
  const space = isNumberNotNaN(options.spaceY) ? options.spaceY : 0;
493
486
  const spaceClient = isNumberNotNaN(options.spaceClient) ? options.spaceClient : 0;
494
- if (target.top < spaceClient || target.bottom + spaceClient > window.innerHeight) {
495
- return {
496
- strategy: void 0,
497
- start: -height
498
- };
499
- }
500
487
  return electPosition(getFollowStrategy(options.followY) || ["after", "before", "start", "end", "center", "ratio"], target.top, target.bottom, height, window.innerHeight, space, spaceClient);
501
488
  }
502
489
  function getFollowStrategy(strategy) {
@@ -901,9 +888,7 @@ var _sfc_main$j = defineComponent({
901
888
  if (__props.popupStatus.value == "closed") {
902
889
  return;
903
890
  }
904
- console.group("%cstart run buildFollow:", "color:red");
905
891
  const targetRect = __props.extOptions.target.getBoundingClientRect();
906
- console.log("-- target:", targetRect, __props.extOptions.target);
907
892
  css.operate(rootDom.value, "add", {
908
893
  style: {
909
894
  width: __props.options.followWidth ? `${targetRect.width}px` : "",
@@ -916,14 +901,12 @@ var _sfc_main$j = defineComponent({
916
901
  const rootRect = rootDom.value.getBoundingClientRect();
917
902
  {
918
903
  const xResult = calcFollowX(__props.options, targetRect, rootRect.width);
919
- console.log("-- follow x:", xResult);
920
904
  followStyle.left = `${xResult.start}px`;
921
905
  xResult.size != void 0 && (followStyle.width = `${xResult.size}px`);
922
906
  followExt.followX.value = xResult.strategy;
923
907
  }
924
908
  {
925
909
  const yResult = calcFollowY(__props.options, targetRect, rootRect.height);
926
- console.log("-- follow y: ", yResult);
927
910
  followStyle.top = `${yResult.start}px`;
928
911
  yResult.size != void 0 && (followStyle.height = `${yResult.size}px`);
929
912
  followExt.followY.value = yResult.strategy;
@@ -941,9 +924,7 @@ var _sfc_main$j = defineComponent({
941
924
  height: rootRect.height
942
925
  });
943
926
  rootDom.value.classList.remove("initial");
944
- console.log("-- content rect: ", rootRect, rootDom.value);
945
927
  }
946
- console.groupEnd();
947
928
  }
948
929
  function onRootSize(size) {
949
930
  const isChange = preSize.width != size.width || preSize.height != size.height;
@@ -959,7 +940,9 @@ var _sfc_main$j = defineComponent({
959
940
  onTimeout(function () {
960
941
  onEvent(window, "resize", () => __props.options.closeOnResize ? closePopup(void 0) : rootDom.value && buildFollow());
961
942
  onEvent(window, "keyup", evet => __props.options.closeOnEscape && evet.key === "Escape" && followExt.pinned.value != true && closePopup(void 0));
962
- onEvent(window, "click", event => __props.options.closeOnMask && rootDom.value != event.target && rootDom.value.contains(event.target) == false && followExt.pinned.value != true && closePopup(void 0));
943
+ onEvent(window, "click", event => {
944
+ __props.options.closeOnMask && followExt.pinned.value != true && rootDom.value != event.target && rootDom.value.contains(event.target) == false && closePopup(void 0);
945
+ });
963
946
  onMutation(rootDom.value, {
964
947
  childList: true,
965
948
  attributes: false,
@@ -1218,7 +1201,7 @@ const _hoisted_1$9 = {
1218
1201
  class: "snail-empty"
1219
1202
  };
1220
1203
  const _hoisted_2$6 = ["src"];
1221
- const _hoisted_3$4 = ["textContent"];
1204
+ const _hoisted_3$5 = ["textContent"];
1222
1205
  var _sfc_main$g = defineComponent({
1223
1206
  ...{
1224
1207
  name: "Empty",
@@ -1238,13 +1221,17 @@ var _sfc_main$g = defineComponent({
1238
1221
  }, null, 8, _hoisted_2$6), renderSlot(_ctx.$slots, "default", {}, () => [createElementVNode("div", {
1239
1222
  class: "message",
1240
1223
  textContent: toDisplayString(props.message || "无数据")
1241
- }, null, 8, _hoisted_3$4)])]);
1224
+ }, null, 8, _hoisted_3$5)])]);
1242
1225
  };
1243
1226
  }
1244
1227
  });
1245
1228
 
1246
1229
  const _hoisted_1$8 = ["title"];
1247
1230
  const _hoisted_2$5 = ["textContent"];
1231
+ const _hoisted_3$4 = {
1232
+ key: 1,
1233
+ class: "select-status"
1234
+ };
1248
1235
  var _sfc_main$f = defineComponent({
1249
1236
  ...{
1250
1237
  name: "SelectNode",
@@ -1294,11 +1281,15 @@ var _sfc_main$f = defineComponent({
1294
1281
  key: 0,
1295
1282
  type: "arrow",
1296
1283
  color: "#8a9099"
1297
- })) : createCommentVNode("", true)], 42, _hoisted_1$8)) : createCommentVNode("", true), showRef.value ? (openBlock(true), createElementBlock(Fragment, {
1284
+ })) : _ctx.multiple == true ? (openBlock(), createElementBlock("div", _hoisted_3$4, [createVNode(_sfc_main$s, {
1285
+ type: "success",
1286
+ color: "white",
1287
+ size: 12
1288
+ })])) : createCommentVNode("", true)], 42, _hoisted_1$8)) : createCommentVNode("", true), showRef.value ? (openBlock(true), createElementBlock(Fragment, {
1298
1289
  key: 1
1299
1290
  }, renderList(unref(showChildrenRef), child => {
1300
1291
  return openBlock(), createBlock(_component_SelectNode, {
1301
- key: child.id || unref(newId)(),
1292
+ key: _ctx.context.getKey(child),
1302
1293
  multiple: _ctx.multiple,
1303
1294
  item: child,
1304
1295
  context: _ctx.context,
@@ -1326,6 +1317,9 @@ var _sfc_main$e = defineComponent({
1326
1317
  showPath: {
1327
1318
  type: Boolean
1328
1319
  },
1320
+ showClear: {
1321
+ type: Boolean
1322
+ },
1329
1323
  popupStyle: {},
1330
1324
  context: {},
1331
1325
  level: {},
@@ -1341,7 +1335,7 @@ var _sfc_main$e = defineComponent({
1341
1335
  followY: {},
1342
1336
  pinned: {}
1343
1337
  },
1344
- emits: ["change"],
1338
+ emits: ["clear", "click"],
1345
1339
  setup(__props, _ref) {
1346
1340
  let {
1347
1341
  emit: __emit
@@ -1370,10 +1364,33 @@ var _sfc_main$e = defineComponent({
1370
1364
  "text-tips": itemsRef.value.length == 0,
1371
1365
  "has-group": itemsRef.value.find(node => node.type == "group") != void 0
1372
1366
  }));
1367
+ const needClearButton = props.multiple == true ? props.level == 1 : props.level == 1 && isStringNotEmpty(context.selectedText(false, props.showPath));
1368
+ const showClearButtonRef = computed(() => needClearButton && props.showClear && (props.multiple ? context.selectedText(true, props.showPath) : true));
1373
1369
  const childDestroyTimerRef = shallowRef(void 0);
1374
1370
  var mouseStatus = "Leave";
1375
1371
  var childFollowTargetDom = void 0;
1376
1372
  var childFollowScope = void 0;
1373
+ function watchOptionsChange() {
1374
+ const inValid = props.multiple == true && itemsRef.value && itemsRef.value.some(item => item.children && item.children.length > 0);
1375
+ if (inValid == true) {
1376
+ const message = "select-popup.vue: select item cannot be multi-level when multiple == true";
1377
+ onTimeout(() => {
1378
+ props.closePopup();
1379
+ alert(message);
1380
+ throw new Error(message);
1381
+ }, 0);
1382
+ }
1383
+ }
1384
+ function emitClickEvent() {
1385
+ for (var _len = arguments.length, path = new Array(_len), _key = 0; _key < _len; _key++) {
1386
+ path[_key] = arguments[_key];
1387
+ }
1388
+ if (popupStatus.value != "closed") {
1389
+ path = path.filter(item => item != void 0);
1390
+ emits("click", path);
1391
+ props.multiple || props.closePopup(path);
1392
+ }
1393
+ }
1377
1394
  function destroyChildFollow(onlyTimer) {
1378
1395
  childDestroyTimerRef.value && childDestroyTimerRef.value.destroy();
1379
1396
  childDestroyTimerRef.value = void 0;
@@ -1398,16 +1415,6 @@ var _sfc_main$e = defineComponent({
1398
1415
  destroyChildFollow();
1399
1416
  context.doSearch(text);
1400
1417
  }
1401
- function onSelected() {
1402
- if (popupStatus.value != "closed") {
1403
- for (var _len = arguments.length, path = new Array(_len), _key = 0; _key < _len; _key++) {
1404
- path[_key] = arguments[_key];
1405
- }
1406
- const values = path.filter(item => item != void 0);
1407
- emits("change", values);
1408
- props.multiple || props.closePopup(values);
1409
- }
1410
- }
1411
1418
  async function onEnterSelectNode(target, node, parent) {
1412
1419
  if (popupStatus.value == "closed") {
1413
1420
  return;
@@ -1430,6 +1437,7 @@ var _sfc_main$e = defineComponent({
1430
1437
  items: node.children,
1431
1438
  context,
1432
1439
  search: void 0,
1440
+ multiple: props.multiple,
1433
1441
  level: props.level + 1,
1434
1442
  popupStyle: props.popupStyle,
1435
1443
  childDestroyTimer: childDestroyTimerRef,
@@ -1437,35 +1445,43 @@ var _sfc_main$e = defineComponent({
1437
1445
  })
1438
1446
  });
1439
1447
  const datas = await childFollowScope;
1440
- isArrayNotEmpty(datas) && onSelected(parent ? parent : void 0, node, ...datas);
1448
+ isArrayNotEmpty(datas) && emitClickEvent(parent ? parent : void 0, node, ...datas);
1441
1449
  popupStatus.value == "open" && onTimeout(() => mouseStatus != "Enter" && onLeavePopup(), 10);
1442
1450
  }
1443
1451
  }
1444
1452
  function onClickSelectNode(node, parent) {
1445
- if (node.clickable == true) {
1446
- onSelected(parent ? parent : void 0, node);
1447
- }
1453
+ node.clickable && emitClickEvent(parent ? parent : void 0, node);
1454
+ }
1455
+ function onClearAllClick() {
1456
+ emits("clear");
1457
+ props.closePopup([]);
1458
+ }
1459
+ {
1460
+ watcher(() => props.multiple, watchOptionsChange);
1461
+ watcher(itemsRef, watchOptionsChange);
1462
+ watchOptionsChange();
1448
1463
  }
1449
1464
  watcher(pinned, newValue => newValue == true && parentPinned && (parentPinned.value = true));
1450
1465
  watcher(popupStatus, newValue => newValue == "closed" && childFollowScope && childFollowScope.destroy());
1451
1466
  return (_ctx, _cache) => {
1452
1467
  return openBlock(), createElementBlock("div", {
1453
1468
  class: normalizeClass(classRef.value),
1454
- style: normalizeStyle(props.popupStyle),
1469
+ style: normalizeStyle(_ctx.popupStyle),
1455
1470
  onMouseenter: onEnterPopup,
1456
1471
  onMouseleave: onLeavePopup
1457
1472
  }, [classRef.value["child-popup"] && classRef.value["text-tips"] ? (openBlock(), createElementBlock(Fragment, {
1458
1473
  key: 0
1459
1474
  }, [createTextVNode(" 暂无选项 ")], 64)) : (openBlock(), createElementBlock(Fragment, {
1460
1475
  key: 1
1461
- }, [props.search ? (openBlock(), createBlock(_sfc_main$o, mergeProps({
1476
+ }, [_ctx.search ? (openBlock(), createBlock(_sfc_main$o, mergeProps({
1462
1477
  key: 0
1463
- }, props.search, {
1464
- onSearch
1478
+ }, _ctx.search, {
1479
+ onSearch,
1480
+ key: "select-search"
1465
1481
  }), null, 16)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(itemsRef.value, item => {
1466
1482
  return openBlock(), createBlock(_sfc_main$f, {
1467
- key: item.id || unref(newId)(),
1468
- multiple: props.multiple,
1483
+ key: unref(context).getKey(item),
1484
+ multiple: _ctx.multiple,
1469
1485
  item,
1470
1486
  context: unref(context),
1471
1487
  "show-children": true,
@@ -1475,7 +1491,11 @@ var _sfc_main$e = defineComponent({
1475
1491
  }), 128)), itemsRef.value.length == 0 ? (openBlock(), createBlock(_sfc_main$g, {
1476
1492
  key: 1,
1477
1493
  message: "无结果"
1478
- })) : createCommentVNode("", true)], 64))], 38);
1494
+ })) : createCommentVNode("", true), showClearButtonRef.value ? (openBlock(), createElementBlock("div", {
1495
+ key: 2,
1496
+ class: "clear-all",
1497
+ onClick: onClearAllClick
1498
+ }, " 清空已选 ")) : createCommentVNode("", true)], 64))], 38);
1479
1499
  };
1480
1500
  }
1481
1501
  });
@@ -1483,6 +1503,7 @@ var _sfc_main$e = defineComponent({
1483
1503
  function useTreeContext(nodes, activeNodeRef) {
1484
1504
  const failed = shallowRef();
1485
1505
  const patched = shallowRef();
1506
+ const nodeKeyMap = new Map();
1486
1507
  function doSearch(text) {
1487
1508
  text = isStringNotEmpty(text) ? text.toLowerCase() : void 0;
1488
1509
  const result = searchTree(nodes, text);
@@ -1510,13 +1531,18 @@ function useTreeContext(nodes, activeNodeRef) {
1510
1531
  function getPath(node) {
1511
1532
  return searchPath(nodes, node);
1512
1533
  }
1534
+ function getKey(node) {
1535
+ nodeKeyMap.has(node) || nodeKeyMap.set(node, newId());
1536
+ return nodeKeyMap.get(node);
1537
+ }
1513
1538
  const context = mountScope({
1514
1539
  doSearch,
1515
1540
  isActived,
1516
1541
  isPatched,
1517
1542
  isShow,
1518
1543
  isShowChildren,
1519
- getPath
1544
+ getPath,
1545
+ getKey
1520
1546
  }, "ITreeBaseContext");
1521
1547
  context.onDestroy(() => {
1522
1548
  failed.value = void 0;
@@ -1568,7 +1594,7 @@ function useSelectContext(items, selectsRef) {
1568
1594
  return false;
1569
1595
  }
1570
1596
  function selectedText(multiple, showPath) {
1571
- if (selectsRef.value) {
1597
+ if (selectsRef.value && selectsRef.value.length) {
1572
1598
  return multiple == true || showPath == true ? selectsRef.value.map(item => item.text).join(multiple ? "、" : " / ") : selectsRef.value[selectsRef.value.length - 1].text;
1573
1599
  }
1574
1600
  return "";
@@ -1619,11 +1645,15 @@ var _sfc_main$d = defineComponent({
1619
1645
  showPath: {
1620
1646
  type: Boolean
1621
1647
  },
1622
- popupStyle: {}
1623
- }, {
1624
- "modelValue": {
1625
- default: []
1648
+ showClear: {
1649
+ type: Boolean
1626
1650
  },
1651
+ popupStyle: {},
1652
+ valuePathDisabled: {
1653
+ type: Boolean
1654
+ }
1655
+ }, {
1656
+ "modelValue": {},
1627
1657
  "modelModifiers": {}
1628
1658
  }),
1629
1659
  emits: mergeModels(["change"], ["update:modelValue"]),
@@ -1641,13 +1671,23 @@ var _sfc_main$d = defineComponent({
1641
1671
  onTimeout
1642
1672
  } = useTimer();
1643
1673
  const rootDom = useTemplateRef("select");
1644
- const context = useSelectContext(props.items, valuesModel);
1645
- const selectTextRef = computed(() => context.selectedText(props.multiple, props.showPath));
1674
+ const selectedItemsRef = computed(() => valuesModel.value ? Array.isArray(valuesModel.value) ? valuesModel.value : [valuesModel.value] : []);
1675
+ const context = useSelectContext(props.items, selectedItemsRef);
1676
+ const selectedTextRef = computed(() => context.selectedText(props.multiple, props.showPath));
1646
1677
  const slotOptions = Object.freeze({
1647
1678
  clear
1648
1679
  });
1649
1680
  var followScope = void 0;
1650
1681
  var stopPropagationScope = void 0;
1682
+ function updateModelValue(newValue, eventValues) {
1683
+ if (valuesModel.value != newValue) {
1684
+ valuesModel.value = newValue;
1685
+ nextTick(() => emits("change", eventValues));
1686
+ }
1687
+ }
1688
+ function isSingleValue() {
1689
+ return props.multiple != true && props.valuePathDisabled == true;
1690
+ }
1651
1691
  function destroyFollow() {
1652
1692
  if (followScope != void 0) {
1653
1693
  followScope.destroy();
@@ -1657,19 +1697,19 @@ var _sfc_main$d = defineComponent({
1657
1697
  return false;
1658
1698
  }
1659
1699
  function clear(closeFollow, stopPropagation) {
1660
- valuesModel.value = [];
1661
1700
  closeFollow && destroyFollow();
1662
1701
  stopPropagationScope && stopPropagationScope.destroy();
1663
1702
  stopPropagationScope = stopPropagation ? onTimeout(() => stopPropagationScope = void 0, 200) : void 0;
1703
+ updateModelValue(isSingleValue() ? void 0 : [], []);
1664
1704
  }
1665
1705
  async function onClick() {
1666
- if (props.readonly == true || rootDom.value == void 0) {
1706
+ if (props.readonly == true || rootDom.value == void 0 || isArrayNotEmpty(props.items) == false) {
1667
1707
  return;
1668
1708
  }
1669
1709
  if (destroyFollow() == true || stopPropagationScope != void 0) {
1670
1710
  return;
1671
1711
  }
1672
- const values = valuesModel.value && valuesModel.value.length > 0 ? [...valuesModel.value] : [];
1712
+ const values = [...selectedItemsRef.value];
1673
1713
  props.multiple != true && values.length > 1 && values.splice(0, values.length - 1);
1674
1714
  context.doSearch(void 0);
1675
1715
  followScope = follow(rootDom.value, {
@@ -1687,17 +1727,28 @@ var _sfc_main$d = defineComponent({
1687
1727
  level: 1,
1688
1728
  search: props.search,
1689
1729
  multiple: props.multiple,
1730
+ showClear: props.showClear,
1690
1731
  popupStyle: props.popupStyle,
1691
- onChange: onSelectItemChange
1732
+ onClick: onSelectItemClick,
1733
+ onClear: () => clear(true, false)
1692
1734
  }
1693
1735
  });
1694
1736
  await followScope;
1695
1737
  followScope = void 0;
1696
1738
  }
1697
- function onSelectItemChange(items) {
1698
- items = hasAny(items) ? [...items] : [];
1699
- valuesModel.value = items;
1700
- nextTick(() => emits("change", items));
1739
+ function onSelectItemClick(path) {
1740
+ path = hasAny(path) ? [...path] : [];
1741
+ if (props.multiple == true) {
1742
+ const node = path[path.length - 1];
1743
+ if (node) {
1744
+ path = [...selectedItemsRef.value];
1745
+ removeFromArray(path, node) == -1 && path.push(node);
1746
+ updateModelValue(path, path);
1747
+ }
1748
+ } else {
1749
+ const newValue = isSingleValue() ? path[path.length - 1] : path;
1750
+ updateModelValue(newValue, path);
1751
+ }
1701
1752
  }
1702
1753
  return (_ctx, _cache) => {
1703
1754
  return openBlock(), createElementBlock("div", {
@@ -1708,10 +1759,10 @@ var _sfc_main$d = defineComponent({
1708
1759
  ref: "select"
1709
1760
  }, [props.items && props.items.length > 0 ? (openBlock(), createElementBlock(Fragment, {
1710
1761
  key: 0
1711
- }, [valuesModel.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$7, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(slotOptions))), () => [createElementVNode("div", {
1762
+ }, [selectedItemsRef.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$7, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(slotOptions))), () => [createElementVNode("div", {
1712
1763
  class: "select-text",
1713
- title: selectTextRef.value,
1714
- textContent: toDisplayString(selectTextRef.value)
1764
+ title: selectedTextRef.value,
1765
+ textContent: toDisplayString(selectedTextRef.value)
1715
1766
  }, null, 8, _hoisted_2$4)])])) : (openBlock(), createElementBlock("div", {
1716
1767
  key: 1,
1717
1768
  class: "select-result text-tips",
@@ -2350,7 +2401,7 @@ var _sfc_main$4 = defineComponent({
2350
2401
  textContent: toDisplayString(_ctx.node.text)
2351
2402
  }, null, 8, _hoisted_2$1), createElementVNode("div", _hoisted_3$1, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(slotOptions))))])], 64))], 34)) : createCommentVNode("", true), showRef.value && showChildrenRef.value ? (openBlock(), createElementBlock("div", _hoisted_4$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.node.children, child => {
2352
2403
  return openBlock(), createBlock(_component_TreeNode, {
2353
- key: child.id || unref(newId)(),
2404
+ key: _ctx.context.getKey(child),
2354
2405
  node: child,
2355
2406
  parent: _ctx.node,
2356
2407
  level: nextLevel,
@@ -2414,7 +2465,7 @@ var _sfc_main$3 = defineComponent({
2414
2465
  }, {
2415
2466
  default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(props.nodes || [], node => {
2416
2467
  return openBlock(), createBlock(_sfc_main$4, {
2417
- key: node.id || unref(newId)(),
2468
+ key: unref(context).getKey(node),
2418
2469
  node,
2419
2470
  parent: void 0,
2420
2471
  level: 1,