@deot/vc-components 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { reactive, defineComponent, createVNode, ref, watch, getCurrentInstance, computed, TransitionGroup, Transition as Transition$1, h, inject, onMounted, provide, shallowRef, onUnmounted, onBeforeUnmount, toRaw, withDirectives, vShow, withModifiers, createApp, Fragment as Fragment$1, Teleport, createTextVNode, mergeProps, nextTick, onUpdated, isVNode, onBeforeMount } from 'vue';
1
+ import { reactive, defineComponent, createVNode, ref, watch, getCurrentInstance, computed, TransitionGroup, Transition as Transition$1, h, inject, onMounted, provide, shallowRef, onUnmounted, nextTick, withDirectives, vShow, isVNode, onBeforeMount, onBeforeUnmount, createApp, Fragment as Fragment$1, Teleport, toRaw, withModifiers, createTextVNode, mergeProps, onUpdated } from 'vue';
2
2
  import { debounce, cloneDeep, throttle, pick, kebabCase } from 'lodash-es';
3
3
  import { Resize } from '@deot/helper-resize';
4
4
  import * as Utils from '@deot/helper-utils';
5
5
  import { getPropByPath, getUid, raf, throttle as throttle$1 } from '@deot/helper-utils';
6
- import { Validator } from '@deot/helper-validator';
7
- import { Utils as Utils$1, IS_SERVER as IS_SERVER$1 } from '@deot/vc-shared';
8
6
  import * as $ from '@deot/helper-dom';
9
7
  import { composedPath } from '@deot/helper-dom';
10
- import { useAttrs, useScrollbar, getInstance } from '@deot/vc-hooks';
8
+ import { Utils as Utils$1, IS_SERVER as IS_SERVER$1 } from '@deot/vc-shared';
9
+ import { useScrollbar, useAttrs, getInstance } from '@deot/vc-hooks';
10
+ import { Validator } from '@deot/helper-validator';
11
11
  import { Storage } from '@deot/helper-cache';
12
12
  import { Interrupter } from '@deot/helper-scheduler';
13
13
  import { Wheel } from '@deot/helper-wheel';
@@ -57,7 +57,7 @@ class Instance {
57
57
  }
58
58
  const VcInstance = new Instance();
59
59
 
60
- const props$1h = {
60
+ const props$1j = {
61
61
  tag: {
62
62
  type: String,
63
63
  default: "div"
@@ -66,10 +66,10 @@ const props$1h = {
66
66
 
67
67
  /** @jsxImportSource vue */
68
68
 
69
- const COMPONENT_NAME$1x = 'vc-action-sheet';
69
+ const COMPONENT_NAME$1A = 'vc-action-sheet';
70
70
  const ActionSheet = /* @__PURE__ */ defineComponent({
71
- name: COMPONENT_NAME$1x,
72
- props: props$1h,
71
+ name: COMPONENT_NAME$1A,
72
+ props: props$1j,
73
73
  setup(props, {
74
74
  slots
75
75
  }) {
@@ -83,7 +83,7 @@ const ActionSheet = /* @__PURE__ */ defineComponent({
83
83
 
84
84
  const MActionSheet = ActionSheet;
85
85
 
86
- const props$1g = {
86
+ const props$1i = {
87
87
  modelValue: {
88
88
  type: Boolean,
89
89
  default: true
@@ -110,7 +110,7 @@ const props$1g = {
110
110
  }
111
111
  };
112
112
 
113
- const props$1f = {
113
+ const props$1h = {
114
114
  type: String,
115
115
  inherit: {
116
116
  type: Boolean,
@@ -163,7 +163,7 @@ class Manager {
163
163
  icons = await this.parser(data, url);
164
164
  try {
165
165
  window.localStorage.setItem(key, JSON.stringify(icons));
166
- } catch (e) {
166
+ } catch {
167
167
  setTimeout(() => {
168
168
  this.clearResource();
169
169
  window.localStorage.setItem(key, JSON.stringify(icons));
@@ -255,10 +255,10 @@ const IconManager = new Manager();
255
255
 
256
256
  /** @jsxImportSource vue */
257
257
 
258
- const COMPONENT_NAME$1w = 'vc-icon';
258
+ const COMPONENT_NAME$1z = 'vc-icon';
259
259
  const Icon = /* @__PURE__ */ defineComponent({
260
- name: COMPONENT_NAME$1w,
261
- props: props$1f,
260
+ name: COMPONENT_NAME$1z,
261
+ props: props$1h,
262
262
  setup(props) {
263
263
  const viewBox = ref('0 0 1024 1024');
264
264
  const path = ref([]);
@@ -291,7 +291,7 @@ const Icon = /* @__PURE__ */ defineComponent({
291
291
  }
292
292
  });
293
293
 
294
- const props$1e = {
294
+ const props$1g = {
295
295
  /**
296
296
  * 进入/离开持续时间
297
297
  * {enter: 300, leave: 300}
@@ -456,10 +456,10 @@ const useTransition = () => {
456
456
  };
457
457
  };
458
458
 
459
- const COMPONENT_NAME$1v = "vc-transition";
459
+ const COMPONENT_NAME$1y = "vc-transition";
460
460
  const Transition = defineComponent({
461
- name: COMPONENT_NAME$1v,
462
- props: props$1e,
461
+ name: COMPONENT_NAME$1y,
462
+ props: props$1g,
463
463
  // 当不声明emits的情况下,事件存在于attrs中
464
464
  inheritAttrs: false,
465
465
  setup(props, { slots, attrs }) {
@@ -479,10 +479,10 @@ const Transition = defineComponent({
479
479
  }
480
480
  });
481
481
 
482
- const COMPONENT_NAME$1u = "vc-transition-collapse";
482
+ const COMPONENT_NAME$1x = "vc-transition-collapse";
483
483
  const TransitionCollapse = defineComponent({
484
- name: COMPONENT_NAME$1u,
485
- props: props$1e,
484
+ name: COMPONENT_NAME$1x,
485
+ props: props$1g,
486
486
  // 当不声明emits的情况下,事件存在于attrs中
487
487
  inheritAttrs: false,
488
488
  setup(props, { slots, attrs: _attrs }) {
@@ -600,11 +600,11 @@ const TransitionCollapse = defineComponent({
600
600
  }
601
601
  });
602
602
 
603
- const COMPONENT_NAME$1t = "vc-transition-fade";
603
+ const COMPONENT_NAME$1w = "vc-transition-fade";
604
604
  const TransitionFade = defineComponent({
605
- name: COMPONENT_NAME$1t,
605
+ name: COMPONENT_NAME$1w,
606
606
  props: {
607
- ...props$1e,
607
+ ...props$1g,
608
608
  // inheritAttrs必须是false
609
609
  style: {
610
610
  type: Object,
@@ -637,11 +637,11 @@ const TransitionFade = defineComponent({
637
637
  }
638
638
  });
639
639
 
640
- const COMPONENT_NAME$1s = "vc-transition-scale";
640
+ const COMPONENT_NAME$1v = "vc-transition-scale";
641
641
  const TransitionScale = defineComponent({
642
- name: COMPONENT_NAME$1s,
642
+ name: COMPONENT_NAME$1v,
643
643
  props: {
644
- ...props$1e,
644
+ ...props$1g,
645
645
  mode: {
646
646
  type: String,
647
647
  default: "both",
@@ -679,15 +679,15 @@ const TransitionScale = defineComponent({
679
679
  }
680
680
  });
681
681
 
682
- const COMPONENT_NAME$1r = "vc-transition-slide";
682
+ const COMPONENT_NAME$1u = "vc-transition-slide";
683
683
  const TransitionSlide = defineComponent({
684
- name: COMPONENT_NAME$1r,
684
+ name: COMPONENT_NAME$1u,
685
685
  props: {
686
- ...props$1e,
686
+ ...props$1g,
687
687
  mode: {
688
688
  type: String,
689
689
  default: "left",
690
- validator: (v) => /^(left|right|down|up|none)(|-part)$/.test(v)
690
+ validator: (v) => /^(left|right|top|bottom|none)(|-part)$/.test(v)
691
691
  },
692
692
  // inheritAttrs必须是false
693
693
  style: {
@@ -721,11 +721,11 @@ const TransitionSlide = defineComponent({
721
721
  }
722
722
  });
723
723
 
724
- const COMPONENT_NAME$1q = "vc-transition-zoom";
724
+ const COMPONENT_NAME$1t = "vc-transition-zoom";
725
725
  const TransitionZoom = defineComponent({
726
- name: COMPONENT_NAME$1q,
726
+ name: COMPONENT_NAME$1t,
727
727
  props: {
728
- ...props$1e,
728
+ ...props$1g,
729
729
  mode: {
730
730
  type: String,
731
731
  default: "x",
@@ -765,7 +765,7 @@ const TransitionZoom = defineComponent({
765
765
 
766
766
  /** @jsxImportSource vue */
767
767
 
768
- const COMPONENT_NAME$1p = 'vc-alert';
768
+ const COMPONENT_NAME$1s = 'vc-alert';
769
769
 
770
770
  // [color, borderColor, backgroundColor], -> CSS
771
771
  const THEME_MAP = {
@@ -775,8 +775,8 @@ const THEME_MAP = {
775
775
  warning: ['#ffbf00', '#ffe58f', '#fffbe6']
776
776
  };
777
777
  const Alert = /* @__PURE__ */ defineComponent({
778
- name: COMPONENT_NAME$1p,
779
- props: props$1g,
778
+ name: COMPONENT_NAME$1s,
779
+ props: props$1i,
780
780
  setup(props, {
781
781
  slots,
782
782
  emit
@@ -865,7 +865,7 @@ const Alert = /* @__PURE__ */ defineComponent({
865
865
 
866
866
  const MAlert = Alert;
867
867
 
868
- const props$1d = {
868
+ const props$1f = {
869
869
  tag: {
870
870
  type: String,
871
871
  default: "div"
@@ -874,10 +874,10 @@ const props$1d = {
874
874
 
875
875
  /** @jsxImportSource vue */
876
876
 
877
- const COMPONENT_NAME$1o = 'vc-artboard';
877
+ const COMPONENT_NAME$1r = 'vc-artboard';
878
878
  const Artboard = /* @__PURE__ */ defineComponent({
879
- name: COMPONENT_NAME$1o,
880
- props: props$1d,
879
+ name: COMPONENT_NAME$1r,
880
+ props: props$1f,
881
881
  setup(props, {
882
882
  slots
883
883
  }) {
@@ -891,7 +891,7 @@ const Artboard = /* @__PURE__ */ defineComponent({
891
891
 
892
892
  const MArtboard = Artboard;
893
893
 
894
- const props$1c = {
894
+ const props$1e = {
895
895
  size: {
896
896
  type: Number,
897
897
  default: 28
@@ -915,10 +915,10 @@ const props$1c = {
915
915
 
916
916
  /** @jsxImportSource vue */
917
917
 
918
- const COMPONENT_NAME$1n = 'vc-spin';
918
+ const COMPONENT_NAME$1q = 'vc-spin';
919
919
  const Spin = /* @__PURE__ */ defineComponent({
920
- name: COMPONENT_NAME$1n,
921
- props: props$1c,
920
+ name: COMPONENT_NAME$1q,
921
+ props: props$1e,
922
922
  setup(props, {
923
923
  slots
924
924
  }) {
@@ -952,7 +952,7 @@ const Spin = /* @__PURE__ */ defineComponent({
952
952
  }
953
953
  });
954
954
 
955
- const props$1b = {
955
+ const props$1d = {
956
956
  wait: {
957
957
  type: Number,
958
958
  default: 250
@@ -968,10 +968,10 @@ const props$1b = {
968
968
  exclude: RegExp
969
969
  };
970
970
 
971
- const COMPONENT_NAME$1m = "vc-debounce";
971
+ const COMPONENT_NAME$1p = "vc-debounce";
972
972
  const Debounce = defineComponent({
973
- name: COMPONENT_NAME$1m,
974
- props: props$1b,
973
+ name: COMPONENT_NAME$1p,
974
+ props: props$1d,
975
975
  /**
976
976
  * 不声明emits使得事件被透传放入attrs中, 这样可以让所有的事件透传
977
977
  * 如事件onClick
@@ -1012,7 +1012,7 @@ const Debounce = defineComponent({
1012
1012
  }
1013
1013
  });
1014
1014
 
1015
- const props$1a = {
1015
+ const props$1c = {
1016
1016
  tag: {
1017
1017
  type: String,
1018
1018
  default: "button"
@@ -1042,18 +1042,18 @@ const props$1a = {
1042
1042
 
1043
1043
  /** @jsxImportSource vue */
1044
1044
 
1045
- const COMPONENT_NAME$1l = 'vc-button';
1045
+ const COMPONENT_NAME$1o = 'vc-button';
1046
1046
  const Button = /* @__PURE__ */ defineComponent({
1047
- name: COMPONENT_NAME$1l,
1047
+ name: COMPONENT_NAME$1o,
1048
1048
  emits: ['click'],
1049
- props: props$1a,
1049
+ props: props$1c,
1050
1050
  setup(props, {
1051
1051
  slots
1052
1052
  }) {
1053
1053
  const vm = getCurrentInstance();
1054
1054
  const hasSlot = ref(true);
1055
1055
  const isLoading = ref(false);
1056
- const group = inject('button-group', {
1056
+ const group = inject('vc-button-group', {
1057
1057
  size: 'medium',
1058
1058
  vertical: false,
1059
1059
  circle: false
@@ -1103,7 +1103,7 @@ const Button = /* @__PURE__ */ defineComponent({
1103
1103
  }
1104
1104
  });
1105
1105
 
1106
- const props$19 = {
1106
+ const props$1b = {
1107
1107
  vertical: {
1108
1108
  type: Boolean,
1109
1109
  default: false
@@ -1124,14 +1124,14 @@ const props$19 = {
1124
1124
 
1125
1125
  /** @jsxImportSource vue */
1126
1126
 
1127
- const COMPONENT_NAME$1k = 'vc-button-group';
1127
+ const COMPONENT_NAME$1n = 'vc-button-group';
1128
1128
  const ButtonGroup = /* @__PURE__ */ defineComponent({
1129
- name: COMPONENT_NAME$1k,
1130
- props: props$19,
1129
+ name: COMPONENT_NAME$1n,
1130
+ props: props$1b,
1131
1131
  setup(props, {
1132
1132
  slots
1133
1133
  }) {
1134
- provide('button-group', props);
1134
+ provide('vc-button-group', props);
1135
1135
  const classes = computed(() => ({
1136
1136
  'is-vertical': props.vertical,
1137
1137
  'is-circle': props.circle,
@@ -1151,7 +1151,7 @@ const ButtonGroup = /* @__PURE__ */ defineComponent({
1151
1151
  const MButton = Button;
1152
1152
  const MButtonGroup = ButtonGroup;
1153
1153
 
1154
- const props$18 = {
1154
+ const props$1a = {
1155
1155
  tag: {
1156
1156
  type: String,
1157
1157
  default: "div"
@@ -1160,10 +1160,10 @@ const props$18 = {
1160
1160
 
1161
1161
  /** @jsxImportSource vue */
1162
1162
 
1163
- const COMPONENT_NAME$1j = 'vc-calendar';
1163
+ const COMPONENT_NAME$1m = 'vc-calendar';
1164
1164
  const Calendar = /* @__PURE__ */ defineComponent({
1165
- name: COMPONENT_NAME$1j,
1166
- props: props$18,
1165
+ name: COMPONENT_NAME$1m,
1166
+ props: props$1a,
1167
1167
  setup(props, {
1168
1168
  slots
1169
1169
  }) {
@@ -1177,7 +1177,7 @@ const Calendar = /* @__PURE__ */ defineComponent({
1177
1177
 
1178
1178
  const MCalendar = Calendar;
1179
1179
 
1180
- const props$17 = {
1180
+ const props$19 = {
1181
1181
  border: {
1182
1182
  type: Boolean,
1183
1183
  default: true
@@ -1200,10 +1200,10 @@ const props$17 = {
1200
1200
 
1201
1201
  /** @jsxImportSource vue */
1202
1202
 
1203
- const COMPONENT_NAME$1i = 'vc-card';
1203
+ const COMPONENT_NAME$1l = 'vc-card';
1204
1204
  const Card = /* @__PURE__ */ defineComponent({
1205
- name: COMPONENT_NAME$1i,
1206
- props: props$17,
1205
+ name: COMPONENT_NAME$1l,
1206
+ props: props$19,
1207
1207
  setup(props, {
1208
1208
  slots
1209
1209
  }) {
@@ -1229,7 +1229,7 @@ const Card = /* @__PURE__ */ defineComponent({
1229
1229
 
1230
1230
  const MCard = Card;
1231
1231
 
1232
- const props$16 = {
1232
+ const props$18 = {
1233
1233
  tag: {
1234
1234
  type: String,
1235
1235
  default: "div"
@@ -1238,10 +1238,10 @@ const props$16 = {
1238
1238
 
1239
1239
  /** @jsxImportSource vue */
1240
1240
 
1241
- const COMPONENT_NAME$1h = 'vc-carousel';
1241
+ const COMPONENT_NAME$1k = 'vc-carousel';
1242
1242
  const Carousel = /* @__PURE__ */ defineComponent({
1243
- name: COMPONENT_NAME$1h,
1244
- props: props$16,
1243
+ name: COMPONENT_NAME$1k,
1244
+ props: props$18,
1245
1245
  setup(props, {
1246
1246
  slots
1247
1247
  }) {
@@ -1255,7 +1255,7 @@ const Carousel = /* @__PURE__ */ defineComponent({
1255
1255
 
1256
1256
  const MCarousel = Carousel;
1257
1257
 
1258
- const props$15 = {
1258
+ const props$17 = {
1259
1259
  tag: {
1260
1260
  type: String,
1261
1261
  default: "div"
@@ -1264,10 +1264,10 @@ const props$15 = {
1264
1264
 
1265
1265
  /** @jsxImportSource vue */
1266
1266
 
1267
- const COMPONENT_NAME$1g = 'vc-cascader';
1267
+ const COMPONENT_NAME$1j = 'vc-cascader';
1268
1268
  const Cascader = /* @__PURE__ */ defineComponent({
1269
- name: COMPONENT_NAME$1g,
1270
- props: props$15,
1269
+ name: COMPONENT_NAME$1j,
1270
+ props: props$17,
1271
1271
  setup(props, {
1272
1272
  slots
1273
1273
  }) {
@@ -1320,7 +1320,7 @@ const EVENTS = [
1320
1320
  "contextmenu"
1321
1321
  ];
1322
1322
 
1323
- const props$14 = {
1323
+ const props$16 = {
1324
1324
  options: Object,
1325
1325
  pluginOptions: Object,
1326
1326
  theme: [String, Object],
@@ -1332,10 +1332,10 @@ const props$14 = {
1332
1332
 
1333
1333
  /** @jsxImportSource vue */
1334
1334
 
1335
- const COMPONENT_NAME$1f = 'vc-chart';
1335
+ const COMPONENT_NAME$1i = 'vc-chart';
1336
1336
  const Chart = /* @__PURE__ */ defineComponent({
1337
- name: COMPONENT_NAME$1f,
1338
- props: props$14,
1337
+ name: COMPONENT_NAME$1i,
1338
+ props: props$16,
1339
1339
  emits: [...EVENTS, 'ready'],
1340
1340
  setup(props, {
1341
1341
  emit,
@@ -1449,7 +1449,7 @@ const Chart = /* @__PURE__ */ defineComponent({
1449
1449
 
1450
1450
  const MChart = Chart;
1451
1451
 
1452
- const props$13 = {
1452
+ const props$15 = {
1453
1453
  tag: {
1454
1454
  type: String,
1455
1455
  default: "div"
@@ -1458,10 +1458,10 @@ const props$13 = {
1458
1458
 
1459
1459
  /** @jsxImportSource vue */
1460
1460
 
1461
- const COMPONENT_NAME$1e = 'vc-checkbox';
1461
+ const COMPONENT_NAME$1h = 'vc-checkbox';
1462
1462
  const Checkbox = /* @__PURE__ */ defineComponent({
1463
- name: COMPONENT_NAME$1e,
1464
- props: props$13,
1463
+ name: COMPONENT_NAME$1h,
1464
+ props: props$15,
1465
1465
  setup(props, {
1466
1466
  slots
1467
1467
  }) {
@@ -1475,7 +1475,7 @@ const Checkbox = /* @__PURE__ */ defineComponent({
1475
1475
 
1476
1476
  const MCheckbox = Checkbox;
1477
1477
 
1478
- const props$12 = {
1478
+ const props$14 = {
1479
1479
  tag: {
1480
1480
  type: String,
1481
1481
  default: "div"
@@ -1484,10 +1484,10 @@ const props$12 = {
1484
1484
 
1485
1485
  /** @jsxImportSource vue */
1486
1486
 
1487
- const COMPONENT_NAME$1d = 'vc-clipboard';
1487
+ const COMPONENT_NAME$1g = 'vc-clipboard';
1488
1488
  const Clipboard = /* @__PURE__ */ defineComponent({
1489
- name: COMPONENT_NAME$1d,
1490
- props: props$12,
1489
+ name: COMPONENT_NAME$1g,
1490
+ props: props$14,
1491
1491
  setup(props, {
1492
1492
  slots
1493
1493
  }) {
@@ -1501,31 +1501,247 @@ const Clipboard = /* @__PURE__ */ defineComponent({
1501
1501
 
1502
1502
  const MClipboard = Clipboard;
1503
1503
 
1504
+ const props$13 = {
1505
+ tag: {
1506
+ type: String,
1507
+ default: "div"
1508
+ },
1509
+ accordion: {
1510
+ type: Boolean,
1511
+ default: false
1512
+ },
1513
+ modelValue: {
1514
+ type: [Array, String, Number]
1515
+ },
1516
+ alive: {
1517
+ type: Boolean,
1518
+ default: true
1519
+ },
1520
+ // TODO: 添加默认样式
1521
+ styleless: {
1522
+ type: Boolean,
1523
+ default: false
1524
+ }
1525
+ };
1526
+
1527
+ const COMPONENT_NAME$1f = "vc-collapse";
1528
+ const Collapse = defineComponent({
1529
+ name: COMPONENT_NAME$1f,
1530
+ props: props$13,
1531
+ emits: ["update:moodelValue", "change"],
1532
+ setup(props, { slots, emit }) {
1533
+ const instance = getCurrentInstance();
1534
+ const currentValue = ref();
1535
+ const items = ref([]);
1536
+ const sync = () => {
1537
+ const v = props.accordion ? currentValue.value[0] : currentValue.value;
1538
+ emit("update:moodelValue", v);
1539
+ emit("change", v);
1540
+ };
1541
+ const setActive = () => {
1542
+ const activeKey = currentValue.value;
1543
+ nextTick(() => {
1544
+ items.value.forEach((child, index) => {
1545
+ const value = typeof child.props.value !== "undefined" ? child.props.value : index;
1546
+ child.exposed.toggle(activeKey.indexOf(value) > -1);
1547
+ });
1548
+ });
1549
+ };
1550
+ const toggle = (item) => {
1551
+ const activeKey = currentValue.value;
1552
+ const index = activeKey.indexOf(item.value);
1553
+ if (!item.visible) {
1554
+ if (index > -1) {
1555
+ activeKey.splice(index, 1);
1556
+ }
1557
+ } else if (index < 0) {
1558
+ activeKey.push(item.value);
1559
+ }
1560
+ currentValue.value = props.accordion ? activeKey.slice(-1) : activeKey;
1561
+ sync();
1562
+ };
1563
+ const add = (item, setValue) => {
1564
+ if (!item) return;
1565
+ nextTick(() => {
1566
+ if (instance.vnode.el) {
1567
+ const index = Array.from(instance.vnode.el.children).filter((i) => /vcm?-collapse-item/.test(i.className)).indexOf(item.vnode.el);
1568
+ if (index != -1) {
1569
+ items.value.splice(index, 0, item);
1570
+ typeof item.props.value === "undefined" && setValue(index);
1571
+ return;
1572
+ }
1573
+ }
1574
+ items.value.push(item);
1575
+ typeof item.props.value === "undefined" && setValue(items.value.length - 1);
1576
+ });
1577
+ };
1578
+ const remove = (item, setValue) => {
1579
+ if (!item) return;
1580
+ items.value.splice(items.value.indexOf(item), 1);
1581
+ items.value.forEach((_, index) => setValue(index));
1582
+ };
1583
+ provide("vc-collapse", {
1584
+ props,
1585
+ toggle,
1586
+ add,
1587
+ remove
1588
+ });
1589
+ watch(
1590
+ () => props.modelValue,
1591
+ (v) => {
1592
+ if (v === currentValue.value) return;
1593
+ currentValue.value = props.accordion && typeof v !== "undefined" ? Array.isArray(v) ? v : [v] : Array.isArray(v) ? v : [];
1594
+ },
1595
+ { immediate: true }
1596
+ );
1597
+ watch(
1598
+ () => currentValue.value,
1599
+ setActive,
1600
+ { deep: true }
1601
+ );
1602
+ onMounted(setActive);
1603
+ return () => {
1604
+ return h(
1605
+ props.tag,
1606
+ {
1607
+ class: [{ "vc-collapse": !props.styleless }]
1608
+ },
1609
+ slots.default?.()
1610
+ );
1611
+ };
1612
+ }
1613
+ });
1614
+
1615
+ const props$12 = {
1616
+ tag: {
1617
+ type: String,
1618
+ default: "div"
1619
+ },
1620
+ value: {
1621
+ type: [String, Number]
1622
+ }
1623
+ };
1624
+
1504
1625
  const props$11 = {
1505
1626
  tag: {
1506
1627
  type: String,
1507
1628
  default: "div"
1629
+ },
1630
+ modelValue: {
1631
+ type: Boolean,
1632
+ default: false
1633
+ },
1634
+ // 子节点每次toggle不销毁
1635
+ alive: {
1636
+ type: Boolean,
1637
+ default: true
1508
1638
  }
1509
1639
  };
1510
1640
 
1511
1641
  /** @jsxImportSource vue */
1512
1642
 
1513
- const COMPONENT_NAME$1c = 'vc-collapse';
1514
- const Collapse = /* @__PURE__ */ defineComponent({
1515
- name: COMPONENT_NAME$1c,
1643
+ function _isSlot$2(s) {
1644
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
1645
+ }
1646
+ const COMPONENT_NAME$1e = 'vc-expand';
1647
+ const Expand = /* @__PURE__ */ defineComponent({
1648
+ name: COMPONENT_NAME$1e,
1516
1649
  props: props$11,
1517
1650
  setup(props, {
1518
1651
  slots
1519
1652
  }) {
1653
+ const isActive = ref(false);
1654
+ const Content = props.tag;
1655
+ watch(() => props.modelValue, v => {
1656
+ isActive.value = v;
1657
+ }, {
1658
+ immediate: true
1659
+ });
1520
1660
  return () => {
1521
- return createVNode("div", {
1522
- "class": "vc-collapse"
1523
- }, [slots?.default?.()]);
1661
+ let _slot;
1662
+ return createVNode(TransitionCollapse, {
1663
+ "duration": {
1664
+ enter: 200,
1665
+ leave: 200
1666
+ }
1667
+ }, _isSlot$2(_slot = withDirectives(createVNode(Content, null, {
1668
+ default: () => [(props.alive || !props.alive && isActive.value) && slots.default?.()]
1669
+ }), [[vShow, isActive.value]])) ? _slot : {
1670
+ default: () => [_slot]
1671
+ });
1672
+ };
1673
+ }
1674
+ });
1675
+
1676
+ /** @jsxImportSource vue */
1677
+
1678
+ const COMPONENT_NAME$1d = 'vc-collapse-item';
1679
+ const CollapseItem = /* @__PURE__ */ defineComponent({
1680
+ name: COMPONENT_NAME$1d,
1681
+ props: props$12,
1682
+ setup(props, {
1683
+ slots,
1684
+ expose
1685
+ }) {
1686
+ const Content = props.tag;
1687
+ const instance = getCurrentInstance();
1688
+ const isActive = ref(false);
1689
+ const current = ref();
1690
+ const collapse = inject('vc-collapse');
1691
+ const handleToggle = () => {
1692
+ collapse.toggle({
1693
+ value: typeof props.value !== 'undefined' ? props.value : current.value,
1694
+ visible: !isActive.value
1695
+ });
1696
+ };
1697
+ const alive = computed(() => {
1698
+ return collapse.props.alive;
1699
+ });
1700
+ const styleless = computed(() => {
1701
+ return collapse.props.styleless;
1702
+ });
1703
+ const setValue = v => current.value = v;
1704
+ onBeforeMount(() => {
1705
+ collapse.add?.(instance, setValue);
1706
+ });
1707
+ onBeforeUnmount(() => {
1708
+ collapse.remove?.(instance, setValue);
1709
+ });
1710
+ expose({
1711
+ isActive,
1712
+ toggle: v => isActive.value = v
1713
+ });
1714
+ return () => {
1715
+ return createVNode(Content, {
1716
+ "class": [{
1717
+ 'vc-collapse-item': !styleless.value
1718
+ }]
1719
+ }, {
1720
+ default: () => [createVNode("div", {
1721
+ "class": [{
1722
+ 'vc-collapse-item__title': !styleless.value
1723
+ }],
1724
+ "onClick": handleToggle
1725
+ }, [slots.default?.(), slots.icon?.({
1726
+ visible: isActive.value
1727
+ })]), createVNode(Expand, {
1728
+ "modelValue": isActive.value,
1729
+ "alive": alive.value,
1730
+ "onChange": v => isActive.value = v
1731
+ }, {
1732
+ default: () => [createVNode("div", {
1733
+ "class": [{
1734
+ 'vc-collapse-item__content': !styleless.value
1735
+ }]
1736
+ }, [slots.content?.()])]
1737
+ })]
1738
+ });
1524
1739
  };
1525
1740
  }
1526
1741
  });
1527
1742
 
1528
1743
  const MCollapse = Collapse;
1744
+ const MCollapseItem = CollapseItem;
1529
1745
 
1530
1746
  const props$10 = {
1531
1747
  tag: {
@@ -1536,9 +1752,9 @@ const props$10 = {
1536
1752
 
1537
1753
  /** @jsxImportSource vue */
1538
1754
 
1539
- const COMPONENT_NAME$1b = 'vc-color-picker';
1755
+ const COMPONENT_NAME$1c = 'vc-color-picker';
1540
1756
  const ColorPicker = /* @__PURE__ */ defineComponent({
1541
- name: COMPONENT_NAME$1b,
1757
+ name: COMPONENT_NAME$1c,
1542
1758
  props: props$10,
1543
1759
  setup(props, {
1544
1760
  slots
@@ -1562,9 +1778,9 @@ const props$$ = {
1562
1778
 
1563
1779
  /** @jsxImportSource vue */
1564
1780
 
1565
- const COMPONENT_NAME$1a = 'vc-countdown';
1781
+ const COMPONENT_NAME$1b = 'vc-countdown';
1566
1782
  const Countdown = /* @__PURE__ */ defineComponent({
1567
- name: COMPONENT_NAME$1a,
1783
+ name: COMPONENT_NAME$1b,
1568
1784
  props: props$$,
1569
1785
  setup(props, {
1570
1786
  slots
@@ -1586,9 +1802,9 @@ const props$_ = {
1586
1802
  }
1587
1803
  };
1588
1804
 
1589
- const COMPONENT_NAME$19 = "vc-customer";
1805
+ const COMPONENT_NAME$1a = "vc-customer";
1590
1806
  const Customer = defineComponent({
1591
- name: COMPONENT_NAME$19,
1807
+ name: COMPONENT_NAME$1a,
1592
1808
  props: props$_,
1593
1809
  setup(props, context) {
1594
1810
  return () => h(() => {
@@ -1608,9 +1824,9 @@ const props$Z = {
1608
1824
 
1609
1825
  /** @jsxImportSource vue */
1610
1826
 
1611
- const COMPONENT_NAME$18 = 'vc-date-picker';
1827
+ const COMPONENT_NAME$19 = 'vc-date-picker';
1612
1828
  const DatePicker = /* @__PURE__ */ defineComponent({
1613
- name: COMPONENT_NAME$18,
1829
+ name: COMPONENT_NAME$19,
1614
1830
  props: props$Z,
1615
1831
  setup(props, {
1616
1832
  slots
@@ -1634,9 +1850,9 @@ const props$Y = {
1634
1850
 
1635
1851
  /** @jsxImportSource vue */
1636
1852
 
1637
- const COMPONENT_NAME$17 = 'vc-divider';
1853
+ const COMPONENT_NAME$18 = 'vc-divider';
1638
1854
  const Divider = /* @__PURE__ */ defineComponent({
1639
- name: COMPONENT_NAME$17,
1855
+ name: COMPONENT_NAME$18,
1640
1856
  props: props$Y,
1641
1857
  setup(props, {
1642
1858
  slots
@@ -1651,1090 +1867,1286 @@ const Divider = /* @__PURE__ */ defineComponent({
1651
1867
 
1652
1868
  const MDivider = Divider;
1653
1869
 
1654
- const props$X = {
1655
- tag: {
1656
- type: String,
1657
- default: "div"
1658
- }
1659
- };
1660
-
1661
- /** @jsxImportSource vue */
1662
-
1663
- const COMPONENT_NAME$16 = 'vc-drawer';
1664
- const Drawer = /* @__PURE__ */ defineComponent({
1665
- name: COMPONENT_NAME$16,
1666
- props: props$X,
1667
- setup(props, {
1668
- slots
1669
- }) {
1670
- return () => {
1671
- return createVNode("div", {
1672
- "class": "vc-drawer"
1673
- }, [slots?.default?.()]);
1674
- };
1675
- }
1676
- });
1677
-
1678
- const MDrawer = Drawer;
1679
-
1680
- const props$W = {
1681
- tag: {
1682
- type: String,
1683
- default: "div"
1684
- }
1685
- };
1686
-
1687
- /** @jsxImportSource vue */
1688
-
1689
- const COMPONENT_NAME$15 = 'vc-dropdown';
1690
- const Dropdown = /* @__PURE__ */ defineComponent({
1691
- name: COMPONENT_NAME$15,
1692
- props: props$W,
1693
- setup(props, {
1694
- slots
1695
- }) {
1696
- return () => {
1697
- return createVNode("div", {
1698
- "class": "vc-dropdown"
1699
- }, [slots?.default?.()]);
1700
- };
1701
- }
1702
- });
1703
-
1704
- const MDropdown = Dropdown;
1705
-
1706
- const props$V = {
1707
- tag: {
1708
- type: String,
1709
- default: "div"
1710
- }
1870
+ const defaults = {
1871
+ tag: "div",
1872
+ el: "body",
1873
+ alive: false,
1874
+ multiple: false,
1875
+ aliveRegExp: { className: /(vc-hack-alive|vc-hack-cp)/ },
1876
+ aliveVisibleKey: "isVisible",
1877
+ aliveUpdateKey: "update",
1878
+ leaveDelay: 300,
1879
+ autoDestroy: true,
1880
+ components: {},
1881
+ uses: {},
1882
+ fragment: false,
1883
+ insertion: "last"
1711
1884
  };
1712
1885
 
1713
- /** @jsxImportSource vue */
1714
-
1715
- const COMPONENT_NAME$14 = 'vc-editor';
1716
- const Editor = /* @__PURE__ */ defineComponent({
1717
- name: COMPONENT_NAME$14,
1718
- props: props$V,
1719
- setup(props, {
1720
- slots
1721
- }) {
1722
- return () => {
1723
- return createVNode("div", {
1724
- "class": "vc-editor"
1725
- }, [slots?.default?.()]);
1886
+ class PortalLeaf {
1887
+ app;
1888
+ /**
1889
+ * 目标的实例,挂载到app上
1890
+ */
1891
+ wrapper;
1892
+ propsData;
1893
+ /**
1894
+ * 销毁的函数,挂载到app上,避免冲突
1895
+ */
1896
+ destroy;
1897
+ /**
1898
+ * 自动销毁的标记,挂载到app上,避免冲突
1899
+ */
1900
+ autoDestroy;
1901
+ target;
1902
+ constructor(target) {
1903
+ this.target = target;
1904
+ this.autoDestroy = false;
1905
+ this.destroy = /* istanbul ignore next */
1906
+ () => {
1907
+ throw new VcError("portal", "未注册的destroy方法");
1726
1908
  };
1727
1909
  }
1728
- });
1729
-
1730
- const MEditor = Editor;
1731
-
1732
- const props$U = {
1733
- tag: {
1734
- type: String,
1735
- default: "div"
1910
+ then(resolve, reject) {
1911
+ return this.target.then(resolve, reject);
1736
1912
  }
1737
- };
1738
-
1739
- /** @jsxImportSource vue */
1740
-
1741
- const COMPONENT_NAME$13 = 'vc-expand';
1742
- const Expand = /* @__PURE__ */ defineComponent({
1743
- name: COMPONENT_NAME$13,
1744
- props: props$U,
1745
- setup(props, {
1746
- slots
1747
- }) {
1748
- return () => {
1749
- return createVNode("div", {
1750
- "class": "vc-expand"
1751
- }, [slots?.default?.()]);
1752
- };
1913
+ catch(callback) {
1914
+ return this.target.catch(callback);
1753
1915
  }
1754
- });
1755
-
1756
- const MExpand = Expand;
1757
-
1758
- const props$T = {
1759
- tag: {
1760
- type: String,
1761
- default: "form"
1762
- },
1763
- model: {
1764
- type: Object
1765
- },
1766
- rules: {
1767
- type: Object
1768
- },
1769
- labelWidth: {
1770
- type: Number
1771
- },
1772
- showMessage: {
1773
- type: Boolean,
1774
- default: true
1775
- },
1776
- inline: {
1777
- type: Boolean,
1778
- default: false
1779
- },
1780
- labelPosition: {
1781
- type: String,
1782
- default: "right"
1783
- },
1784
- autocomplete: {
1785
- type: String,
1786
- default: "off"
1787
- },
1788
- styleless: {
1789
- type: Boolean,
1790
- default: false
1916
+ finally(callback) {
1917
+ return this.target.finally(callback);
1791
1918
  }
1792
- };
1919
+ }
1793
1920
 
1794
- const useForm = (expose, options = {}) => {
1795
- const instance = getCurrentInstance();
1796
- const props = instance.props;
1797
- const fields = [];
1798
- provide("form", {
1799
- props,
1800
- add: (field) => {
1801
- field && fields.push(field);
1802
- },
1803
- remove: (field) => {
1804
- field && fields.splice(fields.indexOf(field), 1);
1805
- }
1806
- });
1807
- const filterFields = (fields$) => {
1808
- return !fields$ ? fields : fields.filter((item) => fields$.includes(item.props.prop));
1809
- };
1810
- const getField = (prop) => {
1811
- const field = fields.find((item) => item.props.prop === prop);
1812
- if (!field) throw new VcError("form", "请选择有用的prop值");
1813
- return field;
1814
- };
1815
- const showToast = (msg) => {
1816
- props.showMessage && options.throwToast?.(msg);
1817
- };
1818
- const sortErrors = async (errors) => {
1819
- const positions = await Promise.all(fields.map((item) => item.exposed.getPosition()));
1921
+ const COMPONENT_NAME$17 = "vc-portal";
1922
+ class Portal {
1923
+ /**
1924
+ * 清理Portals类型组件
1925
+ * @param name 清理的组件名, boolean表示全部leafs是否强制清理
1926
+ */
1927
+ static clear(name) {
1820
1928
  try {
1821
- return [...errors].toSorted((a, b) => {
1822
- const aIndex = fields.findIndex((i) => i.props.prop === a.prop);
1823
- const bIndex = fields.findIndex((i) => i.props.prop === b.prop);
1824
- const aPosition = positions[aIndex];
1825
- const bPosition = positions[bIndex];
1826
- if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
1827
- return aPosition.left - bPosition.left;
1828
- });
1829
- } catch (e) {
1830
- return errors;
1831
- }
1832
- };
1833
- const scrollIntoView = (prop) => {
1834
- const field = getField(prop);
1835
- field.vnode?.el?.scrollIntoView?.({
1836
- behavior: "smooth",
1837
- block: "center"
1838
- });
1839
- };
1840
- const reset = (options$ = {}) => {
1841
- const { fields: fields$, original = {} } = options$;
1842
- filterFields(fields$).forEach((field) => {
1843
- let v;
1844
- try {
1845
- v = getPropByPath(original, field.props.prop).v;
1846
- } catch (e) {
1929
+ let force = false;
1930
+ let target = /* @__PURE__ */ new Map();
1931
+ if (name && typeof name !== "boolean") {
1932
+ let names = [];
1933
+ if (typeof name === "string") {
1934
+ names = [name];
1935
+ } else if (name instanceof Array && name.length > 0) {
1936
+ names = name;
1937
+ }
1938
+ names.forEach((i) => target.set(i, ""));
1939
+ force = true;
1940
+ } else {
1941
+ force = !!name;
1942
+ target = Portal.leafs;
1943
+ }
1944
+ for (const key of target.keys()) {
1945
+ const leaf = Portal.leafs.get(key);
1946
+ if (leaf && (force === true || leaf.autoDestroy === true)) {
1947
+ leaf.destroy();
1948
+ }
1847
1949
  }
1848
- field.exposed.reset(v);
1849
- });
1850
- };
1851
- const validate = async (options$ = {}) => {
1852
- const { scroll = true, fields: fields$ } = options$;
1853
- if (!fields.length) {
1854
- return;
1855
- }
1856
- const results = await Promise.allSettled(
1857
- filterFields(fields$).map((item) => item.exposed.validate(""))
1858
- );
1859
- const originErrors = results.filter((i) => i.status === "rejected").map((i) => i.reason);
1860
- if (!originErrors.length) return;
1861
- const errors = await sortErrors(originErrors);
1862
- showToast(errors[0].msg || errors[0].message);
1863
- scroll && scrollIntoView(errors[0].prop);
1864
- throw errors;
1865
- };
1866
- const validateField = async (prop, options$ = {}) => {
1867
- try {
1868
- await validate({
1869
- ...options$,
1870
- fields: [prop]
1871
- });
1872
1950
  } catch (e) {
1873
- throw e[0];
1951
+ /* istanbul ignore next -- @preserve */
1952
+ throw new VcError("instance", e);
1874
1953
  }
1875
- };
1876
- expose({
1877
- reset,
1878
- validate,
1879
- // 单个操作
1880
- getField,
1881
- validateField
1882
- });
1883
- };
1884
-
1885
- const COMPONENT_NAME$12 = "vc-form";
1886
- const Form = defineComponent({
1887
- name: COMPONENT_NAME$12,
1888
- props: props$T,
1889
- setup(props, { slots, expose }) {
1890
- useForm(expose);
1891
- return () => {
1892
- return h(
1893
- props.tag,
1894
- {
1895
- class: "vc-form",
1896
- autocomplete: props.autocomplete
1897
- },
1898
- slots
1899
- );
1900
- };
1901
1954
  }
1902
- });
1903
-
1904
- const props$S = {
1905
- label: {
1906
- type: String,
1907
- default: ""
1908
- },
1909
- labelWidth: {
1910
- type: Number
1911
- },
1912
- prop: {
1913
- type: String
1914
- },
1915
- required: {
1916
- type: [Boolean, String],
1917
- default: false
1918
- },
1919
- error: {
1920
- type: String
1921
- },
1922
- rules: {
1923
- type: [Array, Object]
1924
- },
1925
- resetByRulesChanged: {
1926
- type: Boolean,
1927
- default: false
1928
- },
1929
- showMessage: {
1930
- type: Boolean,
1931
- default: true
1932
- },
1933
- labelFor: {
1934
- type: String
1935
- },
1936
- styleless: {
1937
- type: Boolean,
1938
- default: false
1939
- },
1940
- labelPosition: {
1941
- type: String,
1942
- default: "right"
1943
- },
1944
- contentStyle: String
1945
- };
1946
-
1947
- const filterEmpty = (val) => {
1948
- if (val instanceof Array) {
1949
- val = val.filter((i) => i !== "");
1955
+ /**
1956
+ * 清理全部Portals
1957
+ */
1958
+ static clearAll() {
1959
+ try {
1960
+ Portal.leafs.forEach((leaf) => leaf.destroy());
1961
+ } catch (e) {
1962
+ /* istanbul ignore next -- @preserve */
1963
+ throw new VcError("instance", e);
1964
+ }
1950
1965
  }
1951
- return val;
1952
- };
1953
- const toRules = (rules) => {
1954
- return rules instanceof Array ? rules : rules ? [rules] : [];
1955
- };
1956
- const useFormItem = (expose) => {
1957
- const form = inject("form");
1958
- const instance = getCurrentInstance();
1959
- const props = instance.props;
1960
- const { slots } = instance;
1961
- if (!form?.props) {
1962
- throw new VcError("form-item", "form-item需要在form内使用");
1966
+ static leafs = /* @__PURE__ */ new Map();
1967
+ wrapper;
1968
+ globalOptions;
1969
+ constructor(wrapper, options) {
1970
+ this.wrapper = wrapper;
1971
+ this.globalOptions = {
1972
+ ...options,
1973
+ name: options?.name || wrapper.name || Utils.getUid(COMPONENT_NAME$17)
1974
+ };
1963
1975
  }
1964
- const formItem = inject("form-item", {});
1965
- const validateState = ref("");
1966
- const validateMessage = ref("");
1967
- let validateDisabled = false;
1968
- let initialValue;
1969
- const currentRules = computed(() => {
1970
- const formRules = form.props.rules;
1971
- const formItemBindRules = toRules(props.rules);
1972
- let formItemRules = formItemBindRules;
1973
- if (!formItemRules.length && formRules && props.prop) {
1974
- try {
1975
- const key = props.prop.replace(/\.[0-9]+\./g, ".");
1976
- const { v } = getPropByPath(formRules, key);
1977
- formItemRules = toRules(v);
1978
- } catch {
1979
- const rules = formRules[props.prop];
1980
- formItemRules = toRules(rules);
1981
- }
1982
- }
1983
- return formItemRules;
1984
- });
1985
- const isRequired = computed(() => {
1986
- if (!currentRules.value.length) {
1987
- return !!props.required;
1976
+ popup(propsData, options) {
1977
+ if (!options) {
1978
+ options = propsData || {};
1979
+ } else {
1980
+ options.propsData = propsData;
1988
1981
  }
1989
- let required = false;
1990
- for (let i = 0; i < currentRules.value.length; i++) {
1991
- const rule = currentRules.value[i];
1992
- required = !!rule.required;
1993
- if (required) break;
1982
+ const $options = { ...this.getDefaultOptions(), ...options };
1983
+ const { onFulfilled, onRejected, ...rest } = $options;
1984
+ let onFulfilled$ = (
1985
+ /* istanbul ignore next -- @preserve */
1986
+ () => {
1987
+ }
1988
+ );
1989
+ let onRejected$ = (
1990
+ /* istanbul ignore next -- @preserve */
1991
+ () => {
1992
+ }
1993
+ );
1994
+ const target = new Promise((resolve, reject) => {
1995
+ onFulfilled$ = (v) => {
1996
+ onFulfilled?.(v);
1997
+ resolve(v);
1998
+ };
1999
+ onRejected$ = (v) => {
2000
+ onRejected?.(v);
2001
+ reject(v);
2002
+ };
2003
+ });
2004
+ return this.render(rest, target, onFulfilled$, onRejected$);
2005
+ }
2006
+ /**
2007
+ * 销毁当前Portal下的节点
2008
+ * @param target [description]
2009
+ */
2010
+ destroy = (target) => {
2011
+ const { multiple, name } = this.getDefaultOptions();
2012
+ target = target || name;
2013
+ const instance = typeof target === "object" ? target : Portal.leafs.get(target);
2014
+ if (instance) {
2015
+ instance.destroy();
2016
+ } else if (multiple) {
2017
+ Portal.leafs.forEach((item, key) => {
2018
+ if (key.includes(name)) {
2019
+ item.destroy();
2020
+ }
2021
+ });
1994
2022
  }
1995
- return required;
1996
- });
1997
- const labelPosition = computed(() => {
1998
- return props.labelPosition || form.props.labelPosition;
1999
- });
2000
- const classes = computed(() => {
2023
+ };
2024
+ getDefaultOptions() {
2001
2025
  return {
2002
- "is-require": isRequired.value,
2003
- "is-error": validateState.value === "error",
2004
- "is-validating": validateState.value === "validating",
2005
- "is-inline": form.props.inline,
2006
- "is-nest": isNest.value,
2007
- [`is-${labelPosition.value}`]: true
2026
+ ...defaults,
2027
+ ...VcInstance.options.Portal,
2028
+ ...this.globalOptions
2008
2029
  };
2009
- });
2010
- const isNest = computed(() => {
2011
- return !!formItem.change;
2012
- });
2013
- const isNestLast = ref(false);
2014
- const hasLabel = computed(() => {
2015
- return !!props.label || slots.label;
2016
- });
2017
- const labelStyle = computed(() => {
2018
- const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNest.value ? 0 : form.props.labelWidth;
2019
- return {
2020
- width: labelPosition.value !== "top" && labelWidth && labelWidth > 0 ? `${labelWidth}px` : "auto",
2021
- textAlign: labelPosition.value === "top" ? "left" : labelPosition.value
2030
+ }
2031
+ createCallback(getLeaf, delay, callback) {
2032
+ return (...args) => {
2033
+ const done = () => {
2034
+ const leaf = getLeaf();
2035
+ /* istanbul ignore next -- @preserve */
2036
+ if (!leaf) {
2037
+ throw new VcError("portal", "实例不存在或已卸载");
2038
+ }
2039
+ leaf.destroy();
2040
+ };
2041
+ delay ? setTimeout(done, delay) : done();
2042
+ callback?.(...args);
2022
2043
  };
2023
- });
2024
- const contentStyle = computed(() => {
2025
- const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : form.props.labelWidth;
2026
- return [
2027
- {
2028
- marginLeft: !hasLabel.value && isNest.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
2029
- marginBottom: isNest.value && !isNestLast.value ? `20px` : 0
2030
- },
2031
- props.contentStyle
2032
- ];
2033
- });
2034
- const isStyleless = computed(() => {
2035
- return props.styleless || form.props.styleless;
2036
- });
2037
- const fieldValue = computed(() => {
2038
- const model = form.props.model;
2039
- if (!model || !props.prop) {
2040
- return;
2041
- }
2042
- let path = props.prop;
2043
- if (path.includes(":")) {
2044
- path = path.replace(/:/, ".");
2045
- }
2046
- return getPropByPath(model, path).v;
2047
- });
2048
- const showError = computed(() => {
2049
- return validateState.value === "error" && props.showMessage && form.props.showMessage;
2050
- });
2051
- watch(
2052
- () => props.error,
2053
- (v) => {
2054
- validateMessage.value = v || "";
2055
- validateState.value = v === "" ? "" : "error";
2056
- }
2057
- );
2058
- const reset = (v) => {
2059
- validateState.value = "";
2060
- validateMessage.value = "";
2061
- const model = form.props.model;
2062
- if (!props.prop) return;
2063
- const { o, k } = getPropByPath(model, props.prop);
2064
- if (!k) return;
2065
- validateDisabled = true;
2066
- o[k] = v !== null && v !== void 0 ? v : Array.isArray(fieldValue.value) ? [].concat(initialValue) : initialValue;
2067
- };
2068
- const validate = async (trigger) => {
2069
- if (!props.prop) return;
2070
- let rules = currentRules.value.filter((rule) => !rule.trigger || rule.trigger.includes(trigger));
2071
- if (!rules.length) {
2072
- if (!props.required) {
2073
- return;
2074
- } else {
2075
- rules = [{
2076
- required: true,
2077
- message: typeof props.required === "string" ? props.required : void 0
2078
- }];
2044
+ }
2045
+ render(options, target, onFulfilled, onRejected) {
2046
+ const {
2047
+ el,
2048
+ tag,
2049
+ alive,
2050
+ aliveRegExp,
2051
+ aliveVisibleKey,
2052
+ aliveUpdateKey,
2053
+ name: name$,
2054
+ leaveDelay,
2055
+ autoDestroy,
2056
+ multiple,
2057
+ fragment,
2058
+ onDestroyed,
2059
+ onBeforeCreate,
2060
+ insertion,
2061
+ // 全局注册
2062
+ globalProperties,
2063
+ install,
2064
+ components,
2065
+ uses,
2066
+ slots,
2067
+ parent,
2068
+ propsData,
2069
+ ...rest
2070
+ } = options;
2071
+ let useAllNodes = fragment;
2072
+ const name = multiple ? `${name$}__${Utils.getUid(COMPONENT_NAME$17)}` : name$;
2073
+ const container = document.createElement(tag);
2074
+ const root = typeof el === "object" ? el : document.querySelector(el || "body");
2075
+ !alive && Portal.leafs.get(name)?.destroy();
2076
+ const propsData$ = propsData || rest;
2077
+ let leaf = new PortalLeaf(target);
2078
+ const isDestroyed = () => {
2079
+ const leaf$ = Portal.leafs.get(name);
2080
+ return !leaf$ || leaf$ !== leaf;
2081
+ };
2082
+ const $onDestroyed = (...args) => {
2083
+ if (isDestroyed()) return;
2084
+ onDestroyed?.(...args);
2085
+ leaf.app?.unmount();
2086
+ /* istanbul ignore else -- @preserve */
2087
+ if (useAllNodes) {
2088
+ root?.contains(container) && root.removeChild(container);
2089
+ } else if (container && container._children) {
2090
+ container._children.forEach((i) => {
2091
+ root?.contains(i) && root.removeChild(i);
2092
+ });
2079
2093
  }
2080
- }
2081
- validateState.value = "validating";
2082
- const descriptor = {};
2083
- descriptor[props.prop] = rules;
2084
- const validator = new Validator(descriptor);
2085
- const model = {};
2086
- model[props.prop] = filterEmpty(fieldValue.value);
2087
- try {
2088
- await validator.validate(model, { first: false });
2089
- validateState.value = "success";
2090
- validateMessage.value = "";
2091
- } catch (errors) {
2092
- validateState.value = "error";
2093
- validateMessage.value = errors[0].message;
2094
- throw {
2095
- prop: props.prop,
2096
- message: validateMessage.value
2097
- };
2098
- }
2099
- validateDisabled = false;
2100
- };
2101
- const handleFieldBlur = () => {
2102
- if (!props.prop) {
2103
- formItem.blur?.();
2104
- return;
2105
- }
2106
- validate("blur");
2107
- };
2108
- const handleFieldChange = () => {
2109
- if (!props.prop) {
2110
- formItem.change?.();
2111
- return;
2112
- }
2113
- if (validateDisabled) {
2114
- validateDisabled = false;
2115
- return;
2116
- }
2117
- validate("change");
2118
- };
2119
- const getPosition = async () => {
2120
- let el = instance.vnode.el;
2121
- try {
2122
- while (el && !el.getBoundingClientRect) {
2123
- el = el.nextSibling;
2094
+ Portal.leafs.delete(name);
2095
+ };
2096
+ const $onRejected = this.createCallback(() => leaf, leaveDelay, onRejected);
2097
+ const $onFulfilled = this.createCallback(() => leaf, leaveDelay, onFulfilled);
2098
+ if (alive && Portal.leafs.has(name)) {
2099
+ leaf = Portal.leafs.get(name);
2100
+ leaf.target = target;
2101
+ leaf.propsData.value = propsData$;
2102
+ leaf.wrapper?.[aliveUpdateKey]?.(options);
2103
+ } else {
2104
+ const wrapper = this.wrapper;
2105
+ const app = createApp({
2106
+ name: COMPONENT_NAME$17,
2107
+ parent,
2108
+ setup() {
2109
+ if (alive) {
2110
+ const handleExtra = (e) => {
2111
+ try {
2112
+ const path = e.path || $.composedPath(e);
2113
+ /* istanbul ignore else -- @preserve */
2114
+ if (container && e.target && !container.contains(e.target) && !path?.some((item) => Utils$1.eleInRegExp(item, aliveRegExp))) {
2115
+ /* istanbul ignore else -- @preserve */
2116
+ if (leaf.wrapper && leaf.wrapper?.[aliveVisibleKey]) {
2117
+ leaf.wrapper[aliveVisibleKey] = false;
2118
+ }
2119
+ leaveDelay ? setTimeout($onDestroyed, leaveDelay) : $onDestroyed();
2120
+ }
2121
+ } catch (error) {
2122
+ /* istanbul ignore next -- @preserve */
2123
+ throw new VcError("portal", error);
2124
+ }
2125
+ };
2126
+ onMounted(() => {
2127
+ document.addEventListener("click", handleExtra, true);
2128
+ });
2129
+ onBeforeUnmount(() => {
2130
+ document.removeEventListener("click", handleExtra, true);
2131
+ });
2132
+ }
2133
+ const propsData1 = ref(propsData$);
2134
+ const propsData2 = ref();
2135
+ leaf.propsData = propsData1;
2136
+ const allowMounted = ref(typeof onBeforeCreate !== "function");
2137
+ if (!allowMounted.value) {
2138
+ const result = onBeforeCreate(propsData$);
2139
+ if (result && result.then) {
2140
+ result.then((response) => {
2141
+ if (isDestroyed()) return;
2142
+ allowMounted.value = true;
2143
+ propsData2.value = response;
2144
+ }).catch((error) => {
2145
+ $onDestroyed(error);
2146
+ });
2147
+ } else {
2148
+ allowMounted.value = true;
2149
+ propsData2.value = result;
2150
+ }
2151
+ }
2152
+ return () => allowMounted.value && h(
2153
+ wrapper,
2154
+ {
2155
+ ...propsData1.value,
2156
+ ...propsData2.value,
2157
+ ref: (vm) => leaf.wrapper = vm,
2158
+ onPortalFulfilled: (...args) => $onFulfilled(...args),
2159
+ onPortalRejected: (...args) => $onRejected(...args),
2160
+ onPortalDestroyed: (...args) => $onDestroyed(...args)
2161
+ },
2162
+ slots || void 0
2163
+ );
2164
+ }
2165
+ });
2166
+ leaf.app = app;
2167
+ if (globalProperties) {
2168
+ app.config.globalProperties = globalProperties;
2124
2169
  }
2125
- ;
2126
- const rect = el.getBoundingClientRect();
2127
- return {
2128
- top: rect.top,
2129
- left: rect.left
2130
- };
2131
- } catch (e) {
2132
- throw new VcError("form-item", "form-item位置计算错误");
2133
- }
2134
- };
2135
- const fields = reactive([]);
2136
- provide("form-item", {
2137
- fields,
2138
- blur: handleFieldBlur,
2139
- change: handleFieldChange,
2140
- message: validateMessage,
2141
- add: (field) => {
2142
- field && fields.push(field);
2143
- },
2144
- remove: (field) => {
2145
- field && fields.splice(fields.indexOf(field), 1);
2146
- }
2147
- });
2148
- onMounted(() => {
2149
- if (props.prop) {
2150
- form.add?.(instance);
2151
- initialValue = cloneDeep(fieldValue.value);
2152
- }
2153
- formItem.add?.(instance);
2154
- });
2155
- onBeforeUnmount(() => {
2156
- form.remove?.(instance);
2157
- formItem.remove?.(instance);
2158
- });
2159
- watch(
2160
- () => props.rules,
2161
- () => {
2162
- props.resetByRulesChanged && reset();
2170
+ for (const key in components) {
2171
+ app.component(key, components[key]);
2172
+ }
2173
+ for (const key in uses) {
2174
+ app.use(uses[key]);
2175
+ }
2176
+ install?.(app);
2177
+ app.mount(container);
2163
2178
  }
2164
- );
2165
- watch(
2166
- () => formItem.fields?.length,
2167
- async (v) => {
2168
- if (!isNest.value || !v) return isNestLast.value = false;
2169
- const fields$ = [...toRaw(formItem.fields)];
2170
- const positions = await Promise.all(fields$.map((item) => item.exposed.getPosition()));
2171
- const sortFields = fields$.toSorted((a, b) => {
2172
- const aIndex = fields$.findIndex((i) => i === a);
2173
- const bIndex = fields$.findIndex((i) => i === b);
2174
- const aPosition = positions[aIndex];
2175
- const bPosition = positions[bIndex];
2176
- if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
2177
- return aPosition.left - bPosition.left;
2179
+ leaf.destroy = $onDestroyed;
2180
+ leaf.autoDestroy = !!autoDestroy;
2181
+ Portal.leafs.set(name, leaf);
2182
+ const append = (root$, child$) => {
2183
+ if (!root$ || !child$) return;
2184
+ if (insertion === "first") {
2185
+ const firstEl = root$.firstElementChild;
2186
+ if (firstEl) {
2187
+ root$.insertBefore(child$, firstEl);
2188
+ return;
2189
+ }
2190
+ }
2191
+ root$.appendChild(child$);
2192
+ };
2193
+ if (fragment || typeof container._children === "undefined" && !Array.from(container.children).length) {
2194
+ useAllNodes = true;
2195
+ container.parentElement === null && append(root, container);
2196
+ } else if (!container._children) {
2197
+ container._children = [];
2198
+ let childs = Array.from(container.children);
2199
+ if (insertion === "first") {
2200
+ childs = childs.reverse();
2201
+ }
2202
+ childs.forEach((i) => {
2203
+ append(root, i);
2204
+ container._children?.push?.(i);
2178
2205
  });
2179
- isNestLast.value = sortFields[sortFields.length - 1] === instance;
2180
2206
  }
2181
- );
2182
- expose({
2183
- validate,
2184
- reset,
2185
- getPosition
2207
+ return leaf;
2208
+ }
2209
+ }
2210
+
2211
+ const props$X = {
2212
+ tag: {
2213
+ type: String,
2214
+ default: "div"
2215
+ }
2216
+ };
2217
+
2218
+ const COMPONENT_NAME$16 = 'vc-portal-view';
2219
+
2220
+ /**
2221
+ * 写法不同,但与vue@2.x 保持一致
2222
+ */
2223
+ const PortalView = /* @__PURE__ */ defineComponent({
2224
+ name: COMPONENT_NAME$16,
2225
+ props: props$X,
2226
+ setup(props, {
2227
+ slots
2228
+ }) {
2229
+ return () => {
2230
+ /**
2231
+ * 考虑占位的情况下需要渲染default
2232
+ */
2233
+ return h(Fragment$1, [h(props.tag, {
2234
+ class: 'vc-portal-view'
2235
+ }, slots?.default?.()), h(Teleport, {
2236
+ to: 'body'
2237
+ }, slots?.content?.())]);
2238
+ };
2239
+ }
2240
+ });
2241
+
2242
+ const props$W = {
2243
+ title: String,
2244
+ content: {
2245
+ type: [String, Function],
2246
+ default: ""
2247
+ },
2248
+ modelValue: {
2249
+ type: Boolean,
2250
+ default: false
2251
+ },
2252
+ width: {
2253
+ type: Number,
2254
+ default: 300
2255
+ },
2256
+ height: {
2257
+ type: Number,
2258
+ default: 300
2259
+ },
2260
+ mask: {
2261
+ type: Boolean,
2262
+ default: true
2263
+ },
2264
+ maskClosable: {
2265
+ type: Boolean,
2266
+ default: true
2267
+ },
2268
+ scrollable: {
2269
+ type: Boolean,
2270
+ default: false
2271
+ },
2272
+ placement: {
2273
+ type: String,
2274
+ default: "right"
2275
+ // top/right/left/bottom
2276
+ },
2277
+ maskStyle: [Object, String],
2278
+ wrapperClass: [Object, String],
2279
+ wrapperStyle: [Object, String],
2280
+ closeWithCancel: {
2281
+ type: Boolean,
2282
+ default: true
2283
+ // 如果关闭, cancel只能是取消的按钮
2284
+ },
2285
+ okText: {
2286
+ type: [String, Boolean],
2287
+ default: "确定"
2288
+ },
2289
+ cancelText: {
2290
+ type: [String, Boolean],
2291
+ default: "取消"
2292
+ },
2293
+ footer: {
2294
+ type: Boolean,
2295
+ default: true
2296
+ },
2297
+ /**
2298
+ * 兼容portal设计, 实现Promise方式
2299
+ */
2300
+ onOk: {
2301
+ type: Function
2302
+ },
2303
+ onCancel: {
2304
+ type: Function
2305
+ }
2306
+ };
2307
+
2308
+ /** @jsxImportSource vue */
2309
+
2310
+ function _isSlot$1(s) {
2311
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
2312
+ }
2313
+ const COMPONENT_NAME$15 = 'vc-drawer';
2314
+ const DrawerView = /* @__PURE__ */ defineComponent({
2315
+ name: COMPONENT_NAME$15,
2316
+ props: props$W,
2317
+ emits: ['close', 'update:modelValue', 'visible-change'],
2318
+ setup(props, {
2319
+ emit,
2320
+ slots,
2321
+ expose
2322
+ }) {
2323
+ const instance = getCurrentInstance();
2324
+ const isActive = ref(false);
2325
+ const classes = computed(() => {
2326
+ return {
2327
+ [`is-${props.placement}`]: true
2328
+ };
2329
+ });
2330
+ const style = computed(() => {
2331
+ return props.placement === 'top' || props.placement === 'bottom' ? {
2332
+ height: `${props.height}px`
2333
+ } : {
2334
+ width: `${props.width}px`
2335
+ };
2336
+ });
2337
+ watch(() => props.modelValue, v => {
2338
+ isActive.value = v;
2339
+ }, {
2340
+ immediate: true
2341
+ });
2342
+ const handleBefore = (e, hook) => {
2343
+ if (!isActive.value) return;
2344
+ const fn = hook && hook(e);
2345
+ if (fn && fn.then) {
2346
+ return fn.then(res => {
2347
+ isActive.value = false;
2348
+ return res;
2349
+ });
2350
+ } else if (!fn || fn === true) {
2351
+ isActive.value = false;
2352
+ }
2353
+ };
2354
+
2355
+ // 关闭事件
2356
+ const handleClose = (e, closable) => {
2357
+ if (closable || props.maskClosable && e.target.classList.contains('vc-drawer__wrapper')) {
2358
+ // 用户主要取消与关闭事件关联
2359
+ if (props.closeWithCancel) {
2360
+ handleBefore(e, handleCancel);
2361
+ } else {
2362
+ isActive.value = false;
2363
+ }
2364
+ }
2365
+ };
2366
+
2367
+ /**
2368
+ * 动画执行后关闭, 关闭事件都会被执行
2369
+ * visible-change 由移除之后触发
2370
+ * 同时close兼容portal设计
2371
+ */
2372
+ const handleRemove = () => {
2373
+ !instance.isUnmounted && (emit('close'), emit('update:modelValue', false), emit('visible-change', false));
2374
+ };
2375
+
2376
+ // 用户点击确定的回调 兼容portal设计
2377
+ const handleOk = (...rest) => {
2378
+ const ok = instance.vnode.props?.onOk || props.onOk || (() => {});
2379
+ return ok(...rest);
2380
+ };
2381
+
2382
+ // 用户点击取消按钮时为取消 兼容portal设计
2383
+ const handleCancel = (...rest) => {
2384
+ const cancel = instance.vnode.props?.onCancel || props.onCancel || (() => {});
2385
+ return cancel(...rest);
2386
+ };
2387
+ useScrollbar(isActive);
2388
+ expose({
2389
+ isActive,
2390
+ // for portal
2391
+ toggle(v) {
2392
+ v = typeof v === 'boolean' ? v : !isActive.value;
2393
+ isActive.value = v;
2394
+ }
2395
+ });
2396
+ return () => {
2397
+ let _slot, _slot2;
2398
+ return createVNode("div", {
2399
+ "class": [classes.value, 'vc-drawer']
2400
+ }, [createVNode(TransitionFade, {
2401
+ "delay": 50
2402
+ }, _isSlot$1(_slot = withDirectives(createVNode("div", {
2403
+ "style": props.maskStyle,
2404
+ "class": "vc-drawer__mask",
2405
+ "onClick": e => handleClose(e, props.maskClosable)
2406
+ }, null), [[vShow, props.mask && isActive.value]])) ? _slot : {
2407
+ default: () => [_slot]
2408
+ }), createVNode(TransitionSlide, {
2409
+ "mode": props.placement,
2410
+ "onAfterLeave": handleRemove
2411
+ }, _isSlot$1(_slot2 = withDirectives(createVNode("div", {
2412
+ "class": [props.wrapperClass, 'vc-drawer__wrapper'],
2413
+ "style": [style.value, props.wrapperStyle]
2414
+ }, [createVNode("div", {
2415
+ "class": "vc-drawer__container"
2416
+ }, [createVNode("div", {
2417
+ "class": "vc-drawer__header"
2418
+ }, [slots.header ? slots.header() : typeof props.title === 'string' ? createVNode("div", {
2419
+ "class": "vc-drawer__title",
2420
+ "innerHTML": props.title
2421
+ }, null) : typeof props.title === 'function' && createVNode(Customer, {
2422
+ "render": props.title
2423
+ }, null), createVNode("a", {
2424
+ "class": "vc-drawer__close",
2425
+ "onClick": e => handleClose(e, true)
2426
+ }, [createVNode(Icon, {
2427
+ "type": "close"
2428
+ }, null)])]), createVNode("div", {
2429
+ "class": ['vc-drawer__content']
2430
+ }, [typeof props.content === 'string' ? createVNode("div", {
2431
+ "innerHTML": props.content
2432
+ }, null) : typeof props.content === 'function' ? createVNode(Customer, {
2433
+ "render": props.content
2434
+ }, null) : null, slots.default?.()]), props.footer && (props.cancelText || props.okText) && createVNode("div", {
2435
+ "class": ['vc-drawer__footer']
2436
+ }, [slots['footer-extra']?.(), !slots.footer ? createVNode(Fragment$1, null, [props.cancelText && createVNode(Button, {
2437
+ "style": "margin-right: 8px;",
2438
+ "onClick": e => handleBefore(e, handleCancel)
2439
+ }, {
2440
+ default: () => [props.cancelText]
2441
+ }), props.okText && createVNode(Button, {
2442
+ "type": "primary",
2443
+ "onClick": e => handleBefore(e, handleOk)
2444
+ }, {
2445
+ default: () => [props.okText]
2446
+ })]) : slots.footer?.()])])]), [[vShow, isActive.value]])) ? _slot2 : {
2447
+ default: () => [_slot2]
2448
+ })]);
2449
+ };
2450
+ }
2451
+ });
2452
+
2453
+ const Drawer = new Portal(DrawerView, {
2454
+ leaveDelay: 0,
2455
+ multiple: true
2456
+ });
2457
+ const destroy$5 = () => Drawer.destroy();
2458
+ const open$1 = (options) => {
2459
+ const leaf = Drawer.popup({
2460
+ ...options,
2461
+ onFulfilled: options.onClose,
2462
+ // 当组件内使用emit('close'),避免重复触发
2463
+ onClose: null
2186
2464
  });
2187
- return {
2188
- isNest,
2189
- isStyleless,
2190
- isNestLast,
2191
- validateMessage,
2192
- classes,
2193
- labelStyle,
2194
- contentStyle,
2195
- showError,
2196
- labelPosition
2197
- };
2465
+ leaf.wrapper.toggle?.(true);
2466
+ return leaf;
2467
+ };
2468
+
2469
+ const drawer = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
2470
+ __proto__: null,
2471
+ destroy: destroy$5,
2472
+ open: open$1
2473
+ }, Symbol.toStringTag, { value: 'Module' }));
2474
+
2475
+ const MDrawerView = DrawerView;
2476
+
2477
+ const props$V = {
2478
+ tag: {
2479
+ type: String,
2480
+ default: "div"
2481
+ }
2482
+ };
2483
+
2484
+ /** @jsxImportSource vue */
2485
+
2486
+ const COMPONENT_NAME$14 = 'vc-dropdown';
2487
+ const Dropdown = /* @__PURE__ */ defineComponent({
2488
+ name: COMPONENT_NAME$14,
2489
+ props: props$V,
2490
+ setup(props, {
2491
+ slots
2492
+ }) {
2493
+ return () => {
2494
+ return createVNode("div", {
2495
+ "class": "vc-dropdown"
2496
+ }, [slots?.default?.()]);
2497
+ };
2498
+ }
2499
+ });
2500
+
2501
+ const MDropdown = Dropdown;
2502
+
2503
+ const props$U = {
2504
+ tag: {
2505
+ type: String,
2506
+ default: "div"
2507
+ }
2198
2508
  };
2199
2509
 
2200
2510
  /** @jsxImportSource vue */
2201
2511
 
2202
- const COMPONENT_NAME$11 = 'vc-form-item';
2203
- const FormItem = /* @__PURE__ */ defineComponent({
2204
- name: COMPONENT_NAME$11,
2205
- props: props$S,
2512
+ const COMPONENT_NAME$13 = 'vc-editor';
2513
+ const Editor = /* @__PURE__ */ defineComponent({
2514
+ name: COMPONENT_NAME$13,
2515
+ props: props$U,
2206
2516
  setup(props, {
2207
- slots,
2208
- expose
2517
+ slots
2209
2518
  }) {
2210
- const it = useFormItem(expose);
2211
- const {
2212
- isStyleless,
2213
- isNest,
2214
- classes,
2215
- labelStyle,
2216
- contentStyle,
2217
- showError,
2218
- validateMessage
2219
- } = it;
2220
- const {
2221
- label,
2222
- labelFor
2223
- } = props;
2224
- const errorColorClass = 'vc-form-item__error';
2225
2519
  return () => {
2226
- if (isStyleless.value) return [slots.default?.(), slots.error?.({
2227
- show: showError.value,
2228
- nest: isNest.value,
2229
- message: validateMessage.value,
2230
- class: errorColorClass
2231
- })];
2232
2520
  return createVNode("div", {
2233
- "class": ['vc-form-item', classes.value]
2234
- }, [createVNode("div", {
2235
- "style": labelStyle.value,
2236
- "class": "vc-form-item__label",
2237
- "for": labelFor
2238
- }, [createVNode("label", null, [label || slots.label?.()])]), createVNode("div", {
2239
- "class": "vc-form-item__wrapper"
2240
- }, [createVNode("div", {
2241
- "class": "vc-form-item__content",
2242
- "style": contentStyle.value
2243
- }, [slots.default?.(), slots.error ? slots.error({
2244
- show: showError.value,
2245
- nest: isNest.value,
2246
- message: validateMessage.value,
2247
- class: errorColorClass
2248
- }) : createVNode(TransitionFade, null, {
2249
- default: () => [withDirectives(createVNode("div", {
2250
- "class": ['vc-form-item__tip', isNest.value ? 'is-nest' : '', errorColorClass]
2251
- }, [validateMessage.value]), [[vShow, showError.value]])]
2252
- })])])]);
2521
+ "class": "vc-editor"
2522
+ }, [slots?.default?.()]);
2253
2523
  };
2254
2524
  }
2255
2525
  });
2256
2526
 
2257
- const props$R = {
2258
- ...props$T,
2259
- showToast: {
2527
+ const MEditor = Editor;
2528
+
2529
+ const MExpand = Expand;
2530
+
2531
+ const props$T = {
2532
+ tag: {
2533
+ type: String,
2534
+ default: "form"
2535
+ },
2536
+ model: {
2537
+ type: Object
2538
+ },
2539
+ rules: {
2540
+ type: Object
2541
+ },
2542
+ labelWidth: {
2543
+ type: Number
2544
+ },
2545
+ showMessage: {
2260
2546
  type: Boolean,
2261
- default: false
2547
+ default: true
2262
2548
  },
2263
- border: {
2549
+ inline: {
2264
2550
  type: Boolean,
2265
2551
  default: false
2266
- }
2267
- };
2268
-
2269
- const props$Q = {
2270
- content: [String, Function],
2271
- maskClosable: {
2272
- type: Boolean,
2273
- default: true
2274
2552
  },
2275
- // 单位ms
2276
- duration: {
2277
- type: Number,
2278
- default: 3e3
2553
+ labelPosition: {
2554
+ type: String,
2555
+ default: "right"
2279
2556
  },
2280
- mode: {
2557
+ autocomplete: {
2281
2558
  type: String,
2282
- default: "info",
2283
- validator: (val) => ["info", "loading", "success", "warning", "error"].includes(val)
2559
+ default: "off"
2560
+ },
2561
+ styleless: {
2562
+ type: Boolean,
2563
+ default: false
2284
2564
  }
2285
2565
  };
2286
2566
 
2287
- const MSpin = Spin;
2288
-
2289
- const MTransition = Transition;
2290
- const MTransitionCollapse = TransitionCollapse;
2291
- const MTransitionFade = TransitionFade;
2292
- const MTransitionScale = TransitionScale;
2293
- const MTransitionSlide = TransitionSlide;
2294
- const MTransitionZoom = TransitionZoom;
2295
-
2296
- /** @jsxImportSource vue */
2297
-
2298
- const COMPONENT_NAME$10 = 'vcm-toast';
2299
- const MToastView = /* @__PURE__ */ defineComponent({
2300
- name: COMPONENT_NAME$10,
2301
- emits: ['close', 'portal-fulfilled'],
2302
- props: props$Q,
2303
- setup(props, {
2304
- emit,
2305
- expose
2306
- }) {
2307
- const isActive = ref(false);
2308
- const currentContent = ref();
2309
- const setContent = v => {
2310
- currentContent.value = v;
2311
- };
2312
-
2313
- // 兼容Portal设计
2314
- const handleRemove = () => {
2315
- emit('close');
2316
- emit('portal-fulfilled');
2317
- };
2318
- const handleClose = () => {
2319
- if (props.maskClosable) {
2320
- isActive.value = false;
2321
- }
2322
- };
2323
- watch(() => props.content, setContent, {
2324
- immediate: true
2567
+ const useForm = (expose, options = {}) => {
2568
+ const instance = getCurrentInstance();
2569
+ const props = instance.props;
2570
+ const fields = [];
2571
+ provide("form", {
2572
+ props,
2573
+ add: (field) => {
2574
+ field && fields.push(field);
2575
+ },
2576
+ remove: (field) => {
2577
+ field && fields.splice(fields.indexOf(field), 1);
2578
+ }
2579
+ });
2580
+ const filterFields = (fields$) => {
2581
+ return !fields$ ? fields : fields.filter((item) => fields$.includes(item.props.prop));
2582
+ };
2583
+ const getField = (prop) => {
2584
+ const field = fields.find((item) => item.props.prop === prop);
2585
+ if (!field) throw new VcError("form", "请选择有用的prop值");
2586
+ return field;
2587
+ };
2588
+ const showToast = (msg) => {
2589
+ props.showMessage && options.throwToast?.(msg);
2590
+ };
2591
+ const sortErrors = async (errors) => {
2592
+ const positions = await Promise.all(fields.map((item) => item.exposed.getPosition()));
2593
+ try {
2594
+ return [...errors].toSorted((a, b) => {
2595
+ const aIndex = fields.findIndex((i) => i.props.prop === a.prop);
2596
+ const bIndex = fields.findIndex((i) => i.props.prop === b.prop);
2597
+ const aPosition = positions[aIndex];
2598
+ const bPosition = positions[bIndex];
2599
+ if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
2600
+ return aPosition.left - bPosition.left;
2601
+ });
2602
+ } catch {
2603
+ return errors;
2604
+ }
2605
+ };
2606
+ const scrollIntoView = (prop) => {
2607
+ const field = getField(prop);
2608
+ field.vnode?.el?.scrollIntoView?.({
2609
+ behavior: "smooth",
2610
+ block: "center"
2325
2611
  });
2326
- let timer;
2327
- onMounted(() => {
2328
- isActive.value = true;
2329
- if (props.duration !== 0) {
2330
- timer = setTimeout(() => isActive.value = false, props.duration);
2612
+ };
2613
+ const reset = (options$ = {}) => {
2614
+ const { fields: fields$, original = {} } = options$;
2615
+ filterFields(fields$).forEach((field) => {
2616
+ let v;
2617
+ try {
2618
+ v = getPropByPath(original, field.props.prop).v;
2619
+ } catch {
2331
2620
  }
2621
+ field.exposed.reset(v);
2332
2622
  });
2333
- onUnmounted(() => {
2334
- timer && clearTimeout(timer);
2335
- });
2336
- const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
2337
- pre[key] = handleRemove;
2338
- return pre;
2339
- }, {});
2340
- expose(exposes);
2623
+ };
2624
+ const validate = async (options$ = {}) => {
2625
+ const { scroll = true, fields: fields$ } = options$;
2626
+ if (!fields.length) {
2627
+ return;
2628
+ }
2629
+ const results = await Promise.allSettled(
2630
+ filterFields(fields$).map((item) => item.exposed.validate(""))
2631
+ );
2632
+ const originErrors = results.filter((i) => i.status === "rejected").map((i) => i.reason);
2633
+ if (!originErrors.length) return;
2634
+ const errors = await sortErrors(originErrors);
2635
+ showToast(errors[0].msg || errors[0].message);
2636
+ scroll && scrollIntoView(errors[0].prop);
2637
+ throw errors;
2638
+ };
2639
+ const validateField = async (prop, options$ = {}) => {
2640
+ try {
2641
+ await validate({
2642
+ ...options$,
2643
+ fields: [prop]
2644
+ });
2645
+ } catch (e) {
2646
+ throw e[0];
2647
+ }
2648
+ };
2649
+ expose({
2650
+ reset,
2651
+ validate,
2652
+ // 单个操作
2653
+ getField,
2654
+ validateField
2655
+ });
2656
+ };
2657
+
2658
+ const COMPONENT_NAME$12 = "vc-form";
2659
+ const Form = defineComponent({
2660
+ name: COMPONENT_NAME$12,
2661
+ props: props$T,
2662
+ setup(props, { slots, expose }) {
2663
+ useForm(expose);
2341
2664
  return () => {
2342
- return createVNode("div", {
2343
- "class": "vcm-toast"
2344
- }, [createVNode("div", {
2345
- "class": "vcm-toast__bg",
2346
- "onClick": handleClose,
2347
- "onTouchmove": withModifiers(() => {}, ['prevent'])
2348
- }, null), createVNode(MTransitionFade, {
2349
- "duration": {
2350
- enter: 300,
2351
- leave: 150
2665
+ return h(
2666
+ props.tag,
2667
+ {
2668
+ class: "vc-form",
2669
+ autocomplete: props.autocomplete
2352
2670
  },
2353
- "onAfterLeave": handleRemove
2354
- }, {
2355
- default: () => [withDirectives(createVNode("div", {
2356
- "class": "vcm-toast__wrapper"
2357
- }, [props.mode === 'loading' && createVNode(MSpin, {
2358
- "class": "vcm-toast__loading"
2359
- }, null), typeof currentContent.value === 'string' ? createVNode("div", {
2360
- "class": "vcm-toast__content",
2361
- "innerHTML": currentContent.value
2362
- }, null) : typeof currentContent.value === 'function' ? createVNode(MCustomer, {
2363
- "render": currentContent.value
2364
- }, null) : null]), [[vShow, isActive.value]])]
2365
- })]);
2671
+ slots
2672
+ );
2366
2673
  };
2367
2674
  }
2368
2675
  });
2369
2676
 
2370
- const defaults = {
2371
- tag: "div",
2372
- el: "body",
2373
- alive: false,
2374
- multiple: false,
2375
- aliveRegExp: { className: /(vc-hack-alive|vc-hack-cp)/ },
2376
- aliveVisibleKey: "isVisible",
2377
- aliveUpdateKey: "update",
2378
- leaveDelay: 300,
2379
- autoDestroy: true,
2380
- components: {},
2381
- uses: {},
2382
- fragment: false,
2383
- insertion: "last"
2677
+ const props$S = {
2678
+ label: {
2679
+ type: String,
2680
+ default: ""
2681
+ },
2682
+ labelWidth: {
2683
+ type: Number
2684
+ },
2685
+ prop: {
2686
+ type: String
2687
+ },
2688
+ required: {
2689
+ type: [Boolean, String],
2690
+ default: false
2691
+ },
2692
+ // 控制`*`是否展示
2693
+ asterisk: {
2694
+ type: Boolean,
2695
+ default: true
2696
+ },
2697
+ error: {
2698
+ type: String
2699
+ },
2700
+ rules: {
2701
+ type: [Array, Object]
2702
+ },
2703
+ resetByRulesChanged: {
2704
+ type: Boolean,
2705
+ default: false
2706
+ },
2707
+ showMessage: {
2708
+ type: Boolean,
2709
+ default: true
2710
+ },
2711
+ labelFor: {
2712
+ type: String
2713
+ },
2714
+ styleless: {
2715
+ type: Boolean,
2716
+ default: false
2717
+ },
2718
+ labelPosition: {
2719
+ type: String,
2720
+ default: "right"
2721
+ },
2722
+ contentStyle: String
2384
2723
  };
2385
2724
 
2386
- class PortalLeaf {
2387
- app;
2388
- /**
2389
- * 目标的实例,挂载到app上
2390
- */
2391
- wrapper;
2392
- propsData;
2393
- /**
2394
- * 销毁的函数,挂载到app上,避免冲突
2395
- */
2396
- destroy;
2397
- /**
2398
- * 自动销毁的标记,挂载到app上,避免冲突
2399
- */
2400
- autoDestroy;
2401
- target;
2402
- constructor(target) {
2403
- this.target = target;
2404
- this.autoDestroy = false;
2405
- this.destroy = /* istanbul ignore next */
2406
- () => {
2407
- throw new VcError("portal", "未注册的destroy方法");
2408
- };
2409
- }
2410
- then(resolve, reject) {
2411
- return this.target.then(resolve, reject);
2412
- }
2413
- catch(callback) {
2414
- return this.target.catch(callback);
2725
+ const filterEmpty = (val) => {
2726
+ if (val instanceof Array) {
2727
+ val = val.filter((i) => i !== "");
2415
2728
  }
2416
- finally(callback) {
2417
- return this.target.finally(callback);
2729
+ return val;
2730
+ };
2731
+ const toRules = (rules) => {
2732
+ return rules instanceof Array ? rules : rules ? [rules] : [];
2733
+ };
2734
+ const useFormItem = (expose) => {
2735
+ const form = inject("form");
2736
+ const instance = getCurrentInstance();
2737
+ const props = instance.props;
2738
+ const { slots } = instance;
2739
+ if (!form?.props) {
2740
+ throw new VcError("form-item", "form-item需要在form内使用");
2418
2741
  }
2419
- }
2420
-
2421
- const COMPONENT_NAME$$ = "vc-portal";
2422
- class Portal {
2423
- /**
2424
- * 清理Portals类型组件
2425
- * @param name 清理的组件名, boolean表示全部leafs是否强制清理
2426
- */
2427
- static clear(name) {
2428
- try {
2429
- let force = false;
2430
- let target = /* @__PURE__ */ new Map();
2431
- if (name && typeof name !== "boolean") {
2432
- let names = [];
2433
- if (typeof name === "string") {
2434
- names = [name];
2435
- } else if (name instanceof Array && name.length > 0) {
2436
- names = name;
2437
- }
2438
- names.forEach((i) => target.set(i, ""));
2439
- force = true;
2742
+ const formItem = inject("vc-form-item", {});
2743
+ const validateState = ref("");
2744
+ const validateMessage = ref("");
2745
+ let validateDisabled = false;
2746
+ let initialValue;
2747
+ const currentRules = computed(() => {
2748
+ const formRules = form.props.rules;
2749
+ const formItemBindRules = toRules(props.rules);
2750
+ let formItemRules = formItemBindRules;
2751
+ if (!formItemRules.length && formRules && props.prop) {
2752
+ try {
2753
+ const key = props.prop.replace(/\.[0-9]+\./g, ".");
2754
+ const { v } = getPropByPath(formRules, key);
2755
+ formItemRules = toRules(v);
2756
+ } catch {
2757
+ const rules = formRules[props.prop];
2758
+ formItemRules = toRules(rules);
2759
+ }
2760
+ }
2761
+ return formItemRules;
2762
+ });
2763
+ const isRequired = computed(() => {
2764
+ if (!currentRules.value.length) {
2765
+ return !!props.required;
2766
+ }
2767
+ let required = false;
2768
+ for (let i = 0; i < currentRules.value.length; i++) {
2769
+ const rule = currentRules.value[i];
2770
+ required = !!rule.required;
2771
+ if (required) break;
2772
+ }
2773
+ return required;
2774
+ });
2775
+ const labelPosition = computed(() => {
2776
+ return props.labelPosition || form.props.labelPosition;
2777
+ });
2778
+ const classes = computed(() => {
2779
+ return {
2780
+ "is-require": isRequired.value && props.asterisk,
2781
+ "is-error": validateState.value === "error",
2782
+ "is-validating": validateState.value === "validating",
2783
+ "is-inline": form.props.inline,
2784
+ "is-nest": isNest.value,
2785
+ [`is-${labelPosition.value}`]: true
2786
+ };
2787
+ });
2788
+ const isNest = computed(() => {
2789
+ return !!formItem.change;
2790
+ });
2791
+ const isNestLast = ref(false);
2792
+ const hasLabel = computed(() => {
2793
+ return !!props.label || slots.label;
2794
+ });
2795
+ const labelStyle = computed(() => {
2796
+ const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNest.value ? 0 : form.props.labelWidth;
2797
+ return {
2798
+ width: labelPosition.value !== "top" && labelWidth && labelWidth > 0 ? `${labelWidth}px` : "auto",
2799
+ textAlign: labelPosition.value === "top" ? "left" : labelPosition.value
2800
+ };
2801
+ });
2802
+ const contentStyle = computed(() => {
2803
+ const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : form.props.labelWidth;
2804
+ return [
2805
+ {
2806
+ marginLeft: !hasLabel.value && isNest.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
2807
+ marginBottom: isNest.value && !isNestLast.value ? `20px` : 0
2808
+ },
2809
+ props.contentStyle
2810
+ ];
2811
+ });
2812
+ const isStyleless = computed(() => {
2813
+ return props.styleless || form.props.styleless;
2814
+ });
2815
+ const fieldValue = computed(() => {
2816
+ const model = form.props.model;
2817
+ if (!model || !props.prop) {
2818
+ return;
2819
+ }
2820
+ let path = props.prop;
2821
+ if (path.includes(":")) {
2822
+ path = path.replace(/:/, ".");
2823
+ }
2824
+ return getPropByPath(model, path).v;
2825
+ });
2826
+ const showError = computed(() => {
2827
+ return validateState.value === "error" && props.showMessage && form.props.showMessage;
2828
+ });
2829
+ watch(
2830
+ () => props.error,
2831
+ (v) => {
2832
+ validateMessage.value = v || "";
2833
+ validateState.value = v === "" ? "" : "error";
2834
+ }
2835
+ );
2836
+ const reset = (v) => {
2837
+ validateState.value = "";
2838
+ validateMessage.value = "";
2839
+ const model = form.props.model;
2840
+ if (!props.prop) return;
2841
+ const { o, k } = getPropByPath(model, props.prop);
2842
+ if (!k) return;
2843
+ validateDisabled = true;
2844
+ o[k] = v !== null && v !== void 0 ? v : Array.isArray(fieldValue.value) ? [].concat(initialValue) : initialValue;
2845
+ };
2846
+ const validate = async (trigger) => {
2847
+ if (!props.prop) return;
2848
+ let rules = currentRules.value.filter((rule) => !rule.trigger || rule.trigger.includes(trigger));
2849
+ if (!rules.length) {
2850
+ if (!props.required) {
2851
+ return;
2440
2852
  } else {
2441
- force = !!name;
2442
- target = Portal.leafs;
2443
- }
2444
- for (const key of target.keys()) {
2445
- const leaf = Portal.leafs.get(key);
2446
- if (leaf && (force === true || leaf.autoDestroy === true)) {
2447
- leaf.destroy();
2448
- }
2853
+ rules = [{
2854
+ required: true,
2855
+ message: typeof props.required === "string" ? props.required : void 0
2856
+ }];
2449
2857
  }
2450
- } catch (e) {
2451
- /* istanbul ignore next -- @preserve */
2452
- throw new VcError("instance", e);
2453
2858
  }
2454
- }
2455
- /**
2456
- * 清理全部Portals
2457
- */
2458
- static clearAll() {
2859
+ validateState.value = "validating";
2860
+ const descriptor = {};
2861
+ descriptor[props.prop] = rules;
2862
+ const validator = new Validator(descriptor);
2863
+ const model = {};
2864
+ model[props.prop] = filterEmpty(fieldValue.value);
2459
2865
  try {
2460
- Portal.leafs.forEach((leaf) => leaf.destroy());
2461
- } catch (e) {
2462
- /* istanbul ignore next -- @preserve */
2463
- throw new VcError("instance", e);
2464
- }
2465
- }
2466
- static leafs = /* @__PURE__ */ new Map();
2467
- wrapper;
2468
- globalOptions;
2469
- constructor(wrapper, options) {
2470
- this.wrapper = wrapper;
2471
- this.globalOptions = {
2472
- ...options,
2473
- name: options?.name || wrapper.name || Utils.getUid(COMPONENT_NAME$$)
2474
- };
2475
- }
2476
- popup(propsData, options) {
2477
- if (!options) {
2478
- options = propsData || {};
2479
- } else {
2480
- options.propsData = propsData;
2481
- }
2482
- const $options = { ...this.getDefaultOptions(), ...options };
2483
- const { onFulfilled, onRejected, ...rest } = $options;
2484
- let onFulfilled$ = (
2485
- /* istanbul ignore next -- @preserve */
2486
- () => {
2487
- }
2488
- );
2489
- let onRejected$ = (
2490
- /* istanbul ignore next -- @preserve */
2491
- () => {
2492
- }
2493
- );
2494
- const target = new Promise((resolve, reject) => {
2495
- onFulfilled$ = (v) => {
2496
- onFulfilled?.(v);
2497
- resolve(v);
2498
- };
2499
- onRejected$ = (v) => {
2500
- onRejected?.(v);
2501
- reject(v);
2866
+ await validator.validate(model, { first: false });
2867
+ validateState.value = "success";
2868
+ validateMessage.value = "";
2869
+ } catch (errors) {
2870
+ validateState.value = "error";
2871
+ validateMessage.value = errors[0].message;
2872
+ throw {
2873
+ prop: props.prop,
2874
+ message: validateMessage.value
2502
2875
  };
2503
- });
2504
- return this.render(rest, target, onFulfilled$, onRejected$);
2505
- }
2506
- /**
2507
- * 销毁当前Portal下的节点
2508
- * @param target [description]
2509
- */
2510
- destroy = (target) => {
2511
- const { multiple, name } = this.getDefaultOptions();
2512
- target = target || name;
2513
- const instance = typeof target === "object" ? target : Portal.leafs.get(target);
2514
- if (instance) {
2515
- instance.destroy();
2516
- } else if (multiple) {
2517
- Portal.leafs.forEach((item, key) => {
2518
- if (key.includes(name)) {
2519
- item.destroy();
2520
- }
2521
- });
2522
2876
  }
2877
+ validateDisabled = false;
2523
2878
  };
2524
- getDefaultOptions() {
2525
- return {
2526
- ...defaults,
2527
- ...VcInstance.options.Portal,
2528
- ...this.globalOptions
2529
- };
2530
- }
2531
- createCallback(getLeaf, delay, callback) {
2532
- return (...args) => {
2533
- const done = () => {
2534
- const leaf = getLeaf();
2535
- /* istanbul ignore next -- @preserve */
2536
- if (!leaf) {
2537
- throw new VcError("portal", "实例不存在或已卸载");
2538
- }
2539
- leaf.destroy();
2540
- };
2541
- delay ? setTimeout(done, delay) : done();
2542
- callback?.(...args);
2543
- };
2544
- }
2545
- render(options, target, onFulfilled, onRejected) {
2546
- const {
2547
- el,
2548
- tag,
2549
- alive,
2550
- aliveRegExp,
2551
- aliveVisibleKey,
2552
- aliveUpdateKey,
2553
- name: name$,
2554
- leaveDelay,
2555
- autoDestroy,
2556
- multiple,
2557
- fragment,
2558
- onDestroyed,
2559
- onBeforeCreate,
2560
- insertion,
2561
- // 全局注册
2562
- globalProperties,
2563
- install,
2564
- components,
2565
- uses,
2566
- slots,
2567
- parent,
2568
- propsData,
2569
- ...rest
2570
- } = options;
2571
- let useAllNodes = fragment;
2572
- const name = multiple ? `${name$}__${Utils.getUid(COMPONENT_NAME$$)}` : name$;
2573
- const container = document.createElement(tag);
2574
- const root = typeof el === "object" ? el : document.querySelector(el || "body");
2575
- !alive && Portal.leafs.get(name)?.destroy();
2576
- const propsData$ = propsData || rest;
2577
- let leaf = new PortalLeaf(target);
2578
- const isDestroyed = () => {
2579
- const leaf$ = Portal.leafs.get(name);
2580
- return !leaf$ || leaf$ !== leaf;
2581
- };
2582
- const $onDestroyed = (...args) => {
2583
- if (isDestroyed()) return;
2584
- onDestroyed?.(...args);
2585
- leaf.app?.unmount();
2586
- /* istanbul ignore else -- @preserve */
2587
- if (useAllNodes) {
2588
- root?.contains(container) && root.removeChild(container);
2589
- } else if (container && container._children) {
2590
- container._children.forEach((i) => {
2591
- root?.contains(i) && root.removeChild(i);
2592
- });
2593
- }
2594
- Portal.leafs.delete(name);
2595
- };
2596
- const $onRejected = this.createCallback(() => leaf, leaveDelay, onRejected);
2597
- const $onFulfilled = this.createCallback(() => leaf, leaveDelay, onFulfilled);
2598
- if (alive && Portal.leafs.has(name)) {
2599
- leaf = Portal.leafs.get(name);
2600
- leaf.target = target;
2601
- leaf.propsData.value = propsData$;
2602
- leaf.wrapper?.[aliveUpdateKey]?.(options);
2603
- } else {
2604
- const wrapper = this.wrapper;
2605
- const app = createApp({
2606
- name: COMPONENT_NAME$$,
2607
- parent,
2608
- setup() {
2609
- if (alive) {
2610
- const handleExtra = (e) => {
2611
- try {
2612
- const path = e.path || $.composedPath(e);
2613
- /* istanbul ignore else -- @preserve */
2614
- if (container && e.target && !container.contains(e.target) && !path?.some((item) => Utils$1.eleInRegExp(item, aliveRegExp))) {
2615
- /* istanbul ignore else -- @preserve */
2616
- if (leaf.wrapper && leaf.wrapper?.[aliveVisibleKey]) {
2617
- leaf.wrapper[aliveVisibleKey] = false;
2618
- }
2619
- leaveDelay ? setTimeout($onDestroyed, leaveDelay) : $onDestroyed();
2620
- }
2621
- } catch (error) {
2622
- /* istanbul ignore next -- @preserve */
2623
- throw new VcError("portal", error);
2624
- }
2625
- };
2626
- onMounted(() => {
2627
- document.addEventListener("click", handleExtra, true);
2628
- });
2629
- onBeforeUnmount(() => {
2630
- document.removeEventListener("click", handleExtra, true);
2631
- });
2632
- }
2633
- const propsData1 = ref(propsData$);
2634
- const propsData2 = ref();
2635
- leaf.propsData = propsData1;
2636
- const allowMounted = ref(typeof onBeforeCreate !== "function");
2637
- if (!allowMounted.value) {
2638
- const result = onBeforeCreate(propsData$);
2639
- if (result && result.then) {
2640
- result.then((response) => {
2641
- if (isDestroyed()) return;
2642
- allowMounted.value = true;
2643
- propsData2.value = response;
2644
- }).catch((error) => {
2645
- $onDestroyed(error);
2646
- });
2647
- } else {
2648
- allowMounted.value = true;
2649
- propsData2.value = result;
2650
- }
2651
- }
2652
- return () => allowMounted.value && h(
2653
- wrapper,
2654
- {
2655
- ...propsData1.value,
2656
- ...propsData2.value,
2657
- ref: (vm) => leaf.wrapper = vm,
2658
- onPortalFulfilled: (...args) => $onFulfilled(...args),
2659
- onPortalRejected: (...args) => $onRejected(...args),
2660
- onPortalDestroyed: (...args) => $onDestroyed(...args)
2661
- },
2662
- slots || void 0
2663
- );
2664
- }
2665
- });
2666
- leaf.app = app;
2667
- if (globalProperties) {
2668
- app.config.globalProperties = globalProperties;
2669
- }
2670
- for (const key in components) {
2671
- app.component(key, components[key]);
2672
- }
2673
- for (const key in uses) {
2674
- app.use(uses[key]);
2675
- }
2676
- install?.(app);
2677
- app.mount(container);
2879
+ const handleFieldBlur = () => {
2880
+ if (!props.prop) {
2881
+ formItem.blur?.();
2882
+ return;
2678
2883
  }
2679
- leaf.destroy = $onDestroyed;
2680
- leaf.autoDestroy = !!autoDestroy;
2681
- Portal.leafs.set(name, leaf);
2682
- const append = (root$, child$) => {
2683
- if (!root$ || !child$) return;
2684
- if (insertion === "first") {
2685
- const firstEl = root$.firstElementChild;
2686
- if (firstEl) {
2687
- root$.insertBefore(child$, firstEl);
2688
- return;
2689
- }
2690
- }
2691
- root$.appendChild(child$);
2692
- };
2693
- if (fragment || typeof container._children === "undefined" && !Array.from(container.children).length) {
2694
- useAllNodes = true;
2695
- container.parentElement === null && append(root, container);
2696
- } else if (!container._children) {
2697
- container._children = [];
2698
- let childs = Array.from(container.children);
2699
- if (insertion === "first") {
2700
- childs = childs.reverse();
2884
+ validate("blur");
2885
+ };
2886
+ const handleFieldChange = () => {
2887
+ if (!props.prop) {
2888
+ formItem.change?.();
2889
+ return;
2890
+ }
2891
+ if (validateDisabled) {
2892
+ validateDisabled = false;
2893
+ return;
2894
+ }
2895
+ validate("change");
2896
+ };
2897
+ const getPosition = async () => {
2898
+ let el = instance.vnode.el;
2899
+ try {
2900
+ while (el && !el.getBoundingClientRect) {
2901
+ el = el.nextSibling;
2701
2902
  }
2702
- childs.forEach((i) => {
2703
- append(root, i);
2704
- container._children?.push?.(i);
2903
+ ;
2904
+ const rect = el.getBoundingClientRect();
2905
+ return {
2906
+ top: rect.top,
2907
+ left: rect.left
2908
+ };
2909
+ } catch {
2910
+ throw new VcError("form-item", "form-item位置计算错误");
2911
+ }
2912
+ };
2913
+ const fields = reactive([]);
2914
+ provide("vc-form-item", {
2915
+ fields,
2916
+ blur: handleFieldBlur,
2917
+ change: handleFieldChange,
2918
+ message: validateMessage,
2919
+ add: (field) => {
2920
+ field && fields.push(field);
2921
+ },
2922
+ remove: (field) => {
2923
+ field && fields.splice(fields.indexOf(field), 1);
2924
+ }
2925
+ });
2926
+ onMounted(() => {
2927
+ if (props.prop) {
2928
+ form.add?.(instance);
2929
+ initialValue = cloneDeep(fieldValue.value);
2930
+ }
2931
+ formItem.add?.(instance);
2932
+ });
2933
+ onBeforeUnmount(() => {
2934
+ form.remove?.(instance);
2935
+ formItem.remove?.(instance);
2936
+ });
2937
+ watch(
2938
+ () => props.rules,
2939
+ () => {
2940
+ props.resetByRulesChanged && reset();
2941
+ }
2942
+ );
2943
+ watch(
2944
+ () => formItem.fields?.length,
2945
+ async (v) => {
2946
+ if (!isNest.value || !v) return isNestLast.value = false;
2947
+ const fields$ = [...toRaw(formItem.fields)];
2948
+ const positions = await Promise.all(fields$.map((item) => item.exposed.getPosition()));
2949
+ const sortFields = fields$.toSorted((a, b) => {
2950
+ const aIndex = fields$.findIndex((i) => i === a);
2951
+ const bIndex = fields$.findIndex((i) => i === b);
2952
+ const aPosition = positions[aIndex];
2953
+ const bPosition = positions[bIndex];
2954
+ if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
2955
+ return aPosition.left - bPosition.left;
2705
2956
  });
2957
+ isNestLast.value = sortFields[sortFields.length - 1] === instance;
2706
2958
  }
2707
- return leaf;
2959
+ );
2960
+ expose({
2961
+ validate,
2962
+ reset,
2963
+ getPosition
2964
+ });
2965
+ return {
2966
+ isNest,
2967
+ isStyleless,
2968
+ isNestLast,
2969
+ validateMessage,
2970
+ classes,
2971
+ labelStyle,
2972
+ contentStyle,
2973
+ showError,
2974
+ labelPosition
2975
+ };
2976
+ };
2977
+
2978
+ /** @jsxImportSource vue */
2979
+
2980
+ const COMPONENT_NAME$11 = 'vc-form-item';
2981
+ const FormItem = /* @__PURE__ */ defineComponent({
2982
+ name: COMPONENT_NAME$11,
2983
+ props: props$S,
2984
+ setup(props, {
2985
+ slots,
2986
+ expose
2987
+ }) {
2988
+ const it = useFormItem(expose);
2989
+ const {
2990
+ isStyleless,
2991
+ isNest,
2992
+ classes,
2993
+ labelStyle,
2994
+ contentStyle,
2995
+ showError,
2996
+ validateMessage
2997
+ } = it;
2998
+ const {
2999
+ label,
3000
+ labelFor
3001
+ } = props;
3002
+ const errorColorClass = 'vc-form-item__error';
3003
+ return () => {
3004
+ if (isStyleless.value) return [slots.default?.(), slots.error?.({
3005
+ show: showError.value,
3006
+ nest: isNest.value,
3007
+ message: validateMessage.value,
3008
+ class: errorColorClass
3009
+ })];
3010
+ return createVNode("div", {
3011
+ "class": ['vc-form-item', classes.value]
3012
+ }, [createVNode("div", {
3013
+ "style": labelStyle.value,
3014
+ "class": "vc-form-item__label",
3015
+ "for": labelFor
3016
+ }, [createVNode("label", null, [label || slots.label?.()])]), createVNode("div", {
3017
+ "class": "vc-form-item__wrapper"
3018
+ }, [createVNode("div", {
3019
+ "class": "vc-form-item__content",
3020
+ "style": contentStyle.value
3021
+ }, [slots.default?.(), slots.error ? slots.error({
3022
+ show: showError.value,
3023
+ nest: isNest.value,
3024
+ message: validateMessage.value,
3025
+ class: errorColorClass
3026
+ }) : createVNode(TransitionFade, null, {
3027
+ default: () => [withDirectives(createVNode("div", {
3028
+ "class": ['vc-form-item__tip', isNest.value ? 'is-nest' : '', errorColorClass]
3029
+ }, [validateMessage.value]), [[vShow, showError.value]])]
3030
+ })])])]);
3031
+ };
2708
3032
  }
2709
- }
3033
+ });
2710
3034
 
2711
- const props$P = {
2712
- tag: {
3035
+ const props$R = {
3036
+ ...props$T,
3037
+ showToast: {
3038
+ type: Boolean,
3039
+ default: false
3040
+ },
3041
+ border: {
3042
+ type: Boolean,
3043
+ default: false
3044
+ }
3045
+ };
3046
+
3047
+ const props$Q = {
3048
+ content: [String, Function],
3049
+ maskClosable: {
3050
+ type: Boolean,
3051
+ default: true
3052
+ },
3053
+ // 单位ms
3054
+ duration: {
3055
+ type: Number,
3056
+ default: 3e3
3057
+ },
3058
+ mode: {
2713
3059
  type: String,
2714
- default: "div"
3060
+ default: "info",
3061
+ validator: (val) => ["info", "loading", "success", "warning", "error"].includes(val)
2715
3062
  }
2716
3063
  };
2717
3064
 
2718
- const COMPONENT_NAME$_ = 'vc-portal-view';
3065
+ const MSpin = Spin;
2719
3066
 
2720
- /**
2721
- * 写法不同,但与vue@2.x 保持一致
2722
- */
2723
- const PortalView = /* @__PURE__ */ defineComponent({
2724
- name: COMPONENT_NAME$_,
2725
- props: props$P,
3067
+ const MTransition = Transition;
3068
+ const MTransitionCollapse = TransitionCollapse;
3069
+ const MTransitionFade = TransitionFade;
3070
+ const MTransitionScale = TransitionScale;
3071
+ const MTransitionSlide = TransitionSlide;
3072
+ const MTransitionZoom = TransitionZoom;
3073
+
3074
+ /** @jsxImportSource vue */
3075
+
3076
+ const COMPONENT_NAME$10 = 'vcm-toast';
3077
+ const MToastView = /* @__PURE__ */ defineComponent({
3078
+ name: COMPONENT_NAME$10,
3079
+ emits: ['close', 'portal-fulfilled'],
3080
+ props: props$Q,
2726
3081
  setup(props, {
2727
- slots
3082
+ emit,
3083
+ expose
2728
3084
  }) {
3085
+ const isActive = ref(false);
3086
+ const currentContent = ref();
3087
+ let timer;
3088
+ const setDuration = v => {
3089
+ timer && clearTimeout(timer);
3090
+ if (v === 0) return;
3091
+ timer = setTimeout(() => isActive.value = false, v);
3092
+ };
3093
+ const setContent = v => {
3094
+ currentContent.value = v;
3095
+ };
3096
+
3097
+ // 兼容Portal设计
3098
+ const handleRemove = () => {
3099
+ emit('close');
3100
+ emit('portal-fulfilled');
3101
+ };
3102
+ const handleClose = () => {
3103
+ if (props.maskClosable) {
3104
+ isActive.value = false;
3105
+ }
3106
+ };
3107
+ watch(() => props.content, setContent, {
3108
+ immediate: true
3109
+ });
3110
+ onMounted(() => {
3111
+ isActive.value = true;
3112
+ setDuration(props.duration);
3113
+ });
3114
+ onUnmounted(() => {
3115
+ timer && clearTimeout(timer);
3116
+ });
3117
+ const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
3118
+ pre[key] = handleRemove;
3119
+ return pre;
3120
+ }, {
3121
+ setContent,
3122
+ setDuration
3123
+ });
3124
+ expose(exposes);
2729
3125
  return () => {
2730
- /**
2731
- * 考虑占位的情况下需要渲染default
2732
- */
2733
- return h(Fragment$1, [h(props.tag, {
2734
- class: 'vc-portal-view'
2735
- }, slots?.default?.()), h(Teleport, {
2736
- to: 'body'
2737
- }, slots?.content?.())]);
3126
+ return createVNode("div", {
3127
+ "class": "vcm-toast"
3128
+ }, [createVNode("div", {
3129
+ "class": "vcm-toast__bg",
3130
+ "onClick": handleClose,
3131
+ "onTouchmove": withModifiers(() => {}, ['prevent'])
3132
+ }, null), createVNode(MTransitionFade, {
3133
+ "duration": {
3134
+ enter: 300,
3135
+ leave: 150
3136
+ },
3137
+ "onAfterLeave": handleRemove
3138
+ }, {
3139
+ default: () => [withDirectives(createVNode("div", {
3140
+ "class": "vcm-toast__wrapper"
3141
+ }, [props.mode === 'loading' && createVNode(MSpin, {
3142
+ "class": "vcm-toast__loading"
3143
+ }, null), typeof currentContent.value === 'string' ? createVNode("div", {
3144
+ "class": "vcm-toast__content",
3145
+ "innerHTML": currentContent.value
3146
+ }, null) : typeof currentContent.value === 'function' ? createVNode(MCustomer, {
3147
+ "render": currentContent.value
3148
+ }, null) : null]), [[vShow, isActive.value]])]
3149
+ })]);
2738
3150
  };
2739
3151
  }
2740
3152
  });
@@ -2774,9 +3186,9 @@ const MToast$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
2774
3186
  warning: warning$3
2775
3187
  }, Symbol.toStringTag, { value: 'Module' }));
2776
3188
 
2777
- const COMPONENT_NAME$Z = "vcm-form";
3189
+ const COMPONENT_NAME$$ = "vcm-form";
2778
3190
  const MForm = defineComponent({
2779
- name: COMPONENT_NAME$Z,
3191
+ name: COMPONENT_NAME$$,
2780
3192
  props: props$R,
2781
3193
  setup(props, { slots, expose }) {
2782
3194
  useForm(expose, {
@@ -2797,7 +3209,7 @@ const MForm = defineComponent({
2797
3209
  }
2798
3210
  });
2799
3211
 
2800
- const props$O = {
3212
+ const props$P = {
2801
3213
  ...props$S,
2802
3214
  indent: {
2803
3215
  type: Number,
@@ -2807,10 +3219,10 @@ const props$O = {
2807
3219
 
2808
3220
  /** @jsxImportSource vue */
2809
3221
 
2810
- const COMPONENT_NAME$Y = 'vcm-form-item';
3222
+ const COMPONENT_NAME$_ = 'vcm-form-item';
2811
3223
  const MFormItem = /* @__PURE__ */ defineComponent({
2812
- name: COMPONENT_NAME$Y,
2813
- props: props$O,
3224
+ name: COMPONENT_NAME$_,
3225
+ props: props$P,
2814
3226
  setup(props, {
2815
3227
  slots,
2816
3228
  expose
@@ -2863,9 +3275,9 @@ const MFormItem = /* @__PURE__ */ defineComponent({
2863
3275
  }
2864
3276
  });
2865
3277
 
2866
- const COMPONENT_NAME$X = "vc-fragment";
3278
+ const COMPONENT_NAME$Z = "vc-fragment";
2867
3279
  const Fragment = defineComponent({
2868
- name: COMPONENT_NAME$X,
3280
+ name: COMPONENT_NAME$Z,
2869
3281
  setup(_, { slots }) {
2870
3282
  return () => h(Fragment$1, slots.default?.());
2871
3283
  }
@@ -2873,7 +3285,7 @@ const Fragment = defineComponent({
2873
3285
 
2874
3286
  const MFragment = Fragment;
2875
3287
 
2876
- const props$N = {
3288
+ const props$O = {
2877
3289
  tag: {
2878
3290
  type: String,
2879
3291
  default: "div"
@@ -2882,10 +3294,10 @@ const props$N = {
2882
3294
 
2883
3295
  /** @jsxImportSource vue */
2884
3296
 
2885
- const COMPONENT_NAME$W = 'vc-html-to-image';
3297
+ const COMPONENT_NAME$Y = 'vc-html-to-image';
2886
3298
  const HTMLToImage = /* @__PURE__ */ defineComponent({
2887
- name: COMPONENT_NAME$W,
2888
- props: props$N,
3299
+ name: COMPONENT_NAME$Y,
3300
+ props: props$O,
2889
3301
  setup(props, {
2890
3302
  slots
2891
3303
  }) {
@@ -2901,7 +3313,7 @@ const MHTMLToImage = HTMLToImage;
2901
3313
 
2902
3314
  const MIcon = Icon;
2903
3315
 
2904
- const props$M = {
3316
+ const props$N = {
2905
3317
  src: String,
2906
3318
  fit: String,
2907
3319
  lazy: Boolean,
@@ -2960,7 +3372,7 @@ const IMGStore$1 = new IMGStore();
2960
3372
 
2961
3373
  /** @jsxImportSource vue */
2962
3374
 
2963
- const COMPONENT_NAME$V = 'vc-image';
3375
+ const COMPONENT_NAME$X = 'vc-image';
2964
3376
  let isSupportObjectFit = false;
2965
3377
  window.addEventListener('DOMContentLoaded', () => {
2966
3378
  isSupportObjectFit = !IS_SERVER$1 && document.documentElement.style.objectFit !== undefined;
@@ -2973,9 +3385,9 @@ const ObjectFit = {
2973
3385
  SCALE_DOWN: 'scale-down'
2974
3386
  };
2975
3387
  const Image = /* @__PURE__ */ defineComponent({
2976
- name: COMPONENT_NAME$V,
3388
+ name: COMPONENT_NAME$X,
2977
3389
  inheritAttrs: false,
2978
- props: props$M,
3390
+ props: props$N,
2979
3391
  setup(props, {
2980
3392
  slots,
2981
3393
  emit
@@ -3169,7 +3581,7 @@ const Image = /* @__PURE__ */ defineComponent({
3169
3581
 
3170
3582
  const MImage = Image;
3171
3583
 
3172
- const props$L = {
3584
+ const props$M = {
3173
3585
  tag: {
3174
3586
  type: String,
3175
3587
  default: "div"
@@ -3178,10 +3590,10 @@ const props$L = {
3178
3590
 
3179
3591
  /** @jsxImportSource vue */
3180
3592
 
3181
- const COMPONENT_NAME$U = 'vc-image-crop';
3593
+ const COMPONENT_NAME$W = 'vc-image-crop';
3182
3594
  const ImageCrop = /* @__PURE__ */ defineComponent({
3183
- name: COMPONENT_NAME$U,
3184
- props: props$L,
3595
+ name: COMPONENT_NAME$W,
3596
+ props: props$M,
3185
3597
  setup(props, {
3186
3598
  slots
3187
3599
  }) {
@@ -3195,7 +3607,7 @@ const ImageCrop = /* @__PURE__ */ defineComponent({
3195
3607
 
3196
3608
  const MImageCrop = ImageCrop;
3197
3609
 
3198
- const props$K = {
3610
+ const props$L = {
3199
3611
  tag: {
3200
3612
  type: String,
3201
3613
  default: "div"
@@ -3204,10 +3616,10 @@ const props$K = {
3204
3616
 
3205
3617
  /** @jsxImportSource vue */
3206
3618
 
3207
- const COMPONENT_NAME$T = 'vc-image-preview';
3619
+ const COMPONENT_NAME$V = 'vc-image-preview';
3208
3620
  const ImagePreview = /* @__PURE__ */ defineComponent({
3209
- name: COMPONENT_NAME$T,
3210
- props: props$K,
3621
+ name: COMPONENT_NAME$V,
3622
+ props: props$L,
3211
3623
  setup(props, {
3212
3624
  slots
3213
3625
  }) {
@@ -3221,7 +3633,7 @@ const ImagePreview = /* @__PURE__ */ defineComponent({
3221
3633
 
3222
3634
  const MImagePreview = ImagePreview;
3223
3635
 
3224
- const props$J = {
3636
+ const props$K = {
3225
3637
  tag: {
3226
3638
  type: String,
3227
3639
  default: "div"
@@ -3230,10 +3642,10 @@ const props$J = {
3230
3642
 
3231
3643
  /** @jsxImportSource vue */
3232
3644
 
3233
- const COMPONENT_NAME$S = 'vc-image-processing';
3645
+ const COMPONENT_NAME$U = 'vc-image-processing';
3234
3646
  const ImageProcessing = /* @__PURE__ */ defineComponent({
3235
- name: COMPONENT_NAME$S,
3236
- props: props$J,
3647
+ name: COMPONENT_NAME$U,
3648
+ props: props$K,
3237
3649
  setup(props, {
3238
3650
  slots
3239
3651
  }) {
@@ -3247,7 +3659,7 @@ const ImageProcessing = /* @__PURE__ */ defineComponent({
3247
3659
 
3248
3660
  const MImageProcessing = ImageProcessing;
3249
3661
 
3250
- const props$I = {
3662
+ const props$J = {
3251
3663
  // Array, 作为select等数组存放临时值
3252
3664
  modelValue: {
3253
3665
  type: [String, Number, Array],
@@ -3346,7 +3758,7 @@ const useInput = (input) => {
3346
3758
  const isFocus = ref(false);
3347
3759
  const isClearing = ref(false);
3348
3760
  const isOnComposition = ref(false);
3349
- const formItem = inject("form-item", {});
3761
+ const formItem = inject("vc-form-item", {});
3350
3762
  watch(
3351
3763
  () => props.modelValue,
3352
3764
  (v) => {
@@ -3501,12 +3913,12 @@ const useNativeEmitter = (input, expose) => {
3501
3913
 
3502
3914
  /** @jsxImportSource vue */
3503
3915
 
3504
- const COMPONENT_NAME$R = 'vc-input';
3916
+ const COMPONENT_NAME$T = 'vc-input';
3505
3917
  const Input = /* @__PURE__ */ defineComponent({
3506
- name: COMPONENT_NAME$R,
3918
+ name: COMPONENT_NAME$T,
3507
3919
  inheritAttrs: false,
3508
3920
  props: {
3509
- ...props$I,
3921
+ ...props$J,
3510
3922
  indicator: {
3511
3923
  type: [Boolean, Object],
3512
3924
  default: false
@@ -3607,8 +4019,8 @@ const Input = /* @__PURE__ */ defineComponent({
3607
4019
  }
3608
4020
  });
3609
4021
 
3610
- const props$H = {
3611
- ...props$I,
4022
+ const props$I = {
4023
+ ...props$J,
3612
4024
  min: {
3613
4025
  type: Number,
3614
4026
  default: 0
@@ -3823,10 +4235,10 @@ const useInputNumber = () => {
3823
4235
 
3824
4236
  /** @jsxImportSource vue */
3825
4237
 
3826
- const COMPONENT_NAME$Q = 'vc-input-number';
4238
+ const COMPONENT_NAME$S = 'vc-input-number';
3827
4239
  const InputNumber = /* @__PURE__ */ defineComponent({
3828
- name: COMPONENT_NAME$Q,
3829
- props: props$H,
4240
+ name: COMPONENT_NAME$S,
4241
+ props: props$I,
3830
4242
  inheritAttrs: false,
3831
4243
  setup(props, {
3832
4244
  slots,
@@ -3877,8 +4289,8 @@ const InputNumber = /* @__PURE__ */ defineComponent({
3877
4289
  }
3878
4290
  });
3879
4291
 
3880
- const props$G = {
3881
- ...props$I,
4292
+ const props$H = {
4293
+ ...props$J,
3882
4294
  enterText: {
3883
4295
  type: [Boolean, String],
3884
4296
  default: true
@@ -3887,10 +4299,10 @@ const props$G = {
3887
4299
 
3888
4300
  /** @jsxImportSource vue */
3889
4301
 
3890
- const COMPONENT_NAME$P = 'vc-input-search';
4302
+ const COMPONENT_NAME$R = 'vc-input-search';
3891
4303
  const InputSearch = /* @__PURE__ */ defineComponent({
3892
- name: COMPONENT_NAME$P,
3893
- props: props$G,
4304
+ name: COMPONENT_NAME$R,
4305
+ props: props$H,
3894
4306
  inheritAttrs: false,
3895
4307
  setup(props, {
3896
4308
  emit,
@@ -3924,12 +4336,12 @@ const InputSearch = /* @__PURE__ */ defineComponent({
3924
4336
 
3925
4337
  /** @jsxImportSource vue */
3926
4338
 
3927
- const COMPONENT_NAME$O = 'vcm-input';
4339
+ const COMPONENT_NAME$Q = 'vcm-input';
3928
4340
  const MInput = /* @__PURE__ */ defineComponent({
3929
- name: COMPONENT_NAME$O,
4341
+ name: COMPONENT_NAME$Q,
3930
4342
  inheritAttrs: false,
3931
4343
  props: {
3932
- ...props$I,
4344
+ ...props$J,
3933
4345
  right: {
3934
4346
  type: Boolean,
3935
4347
  default: false
@@ -4015,10 +4427,10 @@ const MInput = /* @__PURE__ */ defineComponent({
4015
4427
 
4016
4428
  /** @jsxImportSource vue */
4017
4429
 
4018
- const COMPONENT_NAME$N = 'vcm-input-number';
4430
+ const COMPONENT_NAME$P = 'vcm-input-number';
4019
4431
  const MInputNumber = /* @__PURE__ */ defineComponent({
4020
- name: COMPONENT_NAME$N,
4021
- props: props$H,
4432
+ name: COMPONENT_NAME$P,
4433
+ props: props$I,
4022
4434
  inheritAttrs: false,
4023
4435
  setup(props, {
4024
4436
  slots,
@@ -4066,11 +4478,11 @@ const MInputNumber = /* @__PURE__ */ defineComponent({
4066
4478
 
4067
4479
  /** @jsxImportSource vue */
4068
4480
 
4069
- const COMPONENT_NAME$M = 'vcm-input-search';
4481
+ const COMPONENT_NAME$O = 'vcm-input-search';
4070
4482
  const MInputSearch = /* @__PURE__ */ defineComponent({
4071
- name: COMPONENT_NAME$M,
4483
+ name: COMPONENT_NAME$O,
4072
4484
  props: {
4073
- ...props$G,
4485
+ ...props$H,
4074
4486
  cancelText: {
4075
4487
  type: String,
4076
4488
  default: '取消'
@@ -4130,7 +4542,7 @@ const MInputSearch = /* @__PURE__ */ defineComponent({
4130
4542
  }
4131
4543
  });
4132
4544
 
4133
- const props$F = {
4545
+ const props$G = {
4134
4546
  tag: {
4135
4547
  type: String,
4136
4548
  default: "div"
@@ -4145,12 +4557,12 @@ const props$F = {
4145
4557
  }
4146
4558
  };
4147
4559
 
4148
- const COMPONENT_NAME$L = "vcm-list";
4560
+ const COMPONENT_NAME$N = "vcm-list";
4149
4561
  const MList = defineComponent({
4150
- name: COMPONENT_NAME$L,
4151
- props: props$F,
4562
+ name: COMPONENT_NAME$N,
4563
+ props: props$G,
4152
4564
  setup(props, { slots }) {
4153
- provide("list", { props });
4565
+ provide("vc-list", { props });
4154
4566
  return () => {
4155
4567
  return h(
4156
4568
  props.tag,
@@ -4168,7 +4580,7 @@ const MList = defineComponent({
4168
4580
  }
4169
4581
  });
4170
4582
 
4171
- const props$E = {
4583
+ const props$F = {
4172
4584
  tag: {
4173
4585
  type: String,
4174
4586
  default: "div"
@@ -4202,17 +4614,17 @@ const props$E = {
4202
4614
 
4203
4615
  /** @jsxImportSource vue */
4204
4616
 
4205
- const COMPONENT_NAME$K = 'vcm-list-item';
4617
+ const COMPONENT_NAME$M = 'vcm-list-item';
4206
4618
  const HTTP_REGEX = /[a-zA-z]+:\/\/[^\s]*/;
4207
4619
  const MListItem = /* @__PURE__ */ defineComponent({
4208
- name: COMPONENT_NAME$K,
4209
- props: props$E,
4620
+ name: COMPONENT_NAME$M,
4621
+ props: props$F,
4210
4622
  emits: ['click'],
4211
4623
  setup(props, {
4212
4624
  slots,
4213
4625
  emit
4214
4626
  }) {
4215
- const list = inject('list', {});
4627
+ const list = inject('vc-list', {});
4216
4628
  const classes = computed(() => {
4217
4629
  const hasList = !!list.props;
4218
4630
  return {
@@ -4280,7 +4692,7 @@ const MListItem = /* @__PURE__ */ defineComponent({
4280
4692
  }
4281
4693
  });
4282
4694
 
4283
- const props$D = {
4695
+ const props$E = {
4284
4696
  tag: {
4285
4697
  type: String,
4286
4698
  default: "div"
@@ -4289,10 +4701,10 @@ const props$D = {
4289
4701
 
4290
4702
  /** @jsxImportSource vue */
4291
4703
 
4292
- const COMPONENT_NAME$J = 'vc-marquee';
4704
+ const COMPONENT_NAME$L = 'vc-marquee';
4293
4705
  const Marquee = /* @__PURE__ */ defineComponent({
4294
- name: COMPONENT_NAME$J,
4295
- props: props$D,
4706
+ name: COMPONENT_NAME$L,
4707
+ props: props$E,
4296
4708
  setup(props, {
4297
4709
  slots
4298
4710
  }) {
@@ -4306,7 +4718,7 @@ const Marquee = /* @__PURE__ */ defineComponent({
4306
4718
 
4307
4719
  const MMarquee = Marquee;
4308
4720
 
4309
- const props$C = {
4721
+ const props$D = {
4310
4722
  content: [String, Function],
4311
4723
  mask: {
4312
4724
  type: Boolean,
@@ -4344,11 +4756,11 @@ const props$C = {
4344
4756
 
4345
4757
  /** @jsxImportSource vue */
4346
4758
 
4347
- const COMPONENT_NAME$I = 'vc-message';
4759
+ const COMPONENT_NAME$K = 'vc-message';
4348
4760
  const MessageView = /* @__PURE__ */ defineComponent({
4349
- name: COMPONENT_NAME$I,
4761
+ name: COMPONENT_NAME$K,
4350
4762
  emits: ['before-close', 'close', 'portal-fulfilled'],
4351
- props: props$C,
4763
+ props: props$D,
4352
4764
  setup(props, {
4353
4765
  emit,
4354
4766
  expose
@@ -4356,6 +4768,12 @@ const MessageView = /* @__PURE__ */ defineComponent({
4356
4768
  const instance = getCurrentInstance();
4357
4769
  const isActive = ref(false);
4358
4770
  const currentContent = ref();
4771
+ let timer;
4772
+ const setDuration = v => {
4773
+ timer && clearTimeout(timer);
4774
+ if (v === 0) return;
4775
+ timer = setTimeout(() => isActive.value = false, v);
4776
+ };
4359
4777
  const setContent = v => {
4360
4778
  currentContent.value = v;
4361
4779
  };
@@ -4381,12 +4799,9 @@ const MessageView = /* @__PURE__ */ defineComponent({
4381
4799
  watch(() => props.content, setContent, {
4382
4800
  immediate: true
4383
4801
  });
4384
- let timer;
4385
4802
  onMounted(() => {
4386
4803
  isActive.value = true;
4387
- if (props.duration !== 0) {
4388
- timer = setTimeout(() => isActive.value = false, props.duration);
4389
- }
4804
+ setDuration(props.duration);
4390
4805
  });
4391
4806
  onUnmounted(() => {
4392
4807
  timer && clearTimeout(timer);
@@ -4395,7 +4810,8 @@ const MessageView = /* @__PURE__ */ defineComponent({
4395
4810
  pre[key] = handleRemove;
4396
4811
  return pre;
4397
4812
  }, {
4398
- setContent
4813
+ setContent,
4814
+ setDuration
4399
4815
  });
4400
4816
  expose(exposes);
4401
4817
  return () => {
@@ -4405,7 +4821,7 @@ const MessageView = /* @__PURE__ */ defineComponent({
4405
4821
  "class": "vc-message__mask",
4406
4822
  "onClick": e => handleClose(e, props.maskClosable)
4407
4823
  }, null), createVNode(TransitionSlide, {
4408
- "mode": "up",
4824
+ "mode": "bottom",
4409
4825
  "onAfterLeave": handleRemove
4410
4826
  }, {
4411
4827
  default: () => [withDirectives(createVNode("div", {
@@ -4485,7 +4901,7 @@ const Message$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty(
4485
4901
 
4486
4902
  const MMessage = Message$1;
4487
4903
 
4488
- const props$B = {
4904
+ const props$C = {
4489
4905
  modelValue: {
4490
4906
  type: Boolean,
4491
4907
  default: false
@@ -4565,12 +4981,12 @@ const props$B = {
4565
4981
 
4566
4982
  /** @jsxImportSource vue */
4567
4983
 
4568
- const COMPONENT_NAME$H = 'vc-modal';
4984
+ const COMPONENT_NAME$J = 'vc-modal';
4569
4985
  let zIndexNumber = 1002;
4570
4986
  const ModalView = /* @__PURE__ */ defineComponent({
4571
- name: COMPONENT_NAME$H,
4987
+ name: COMPONENT_NAME$J,
4572
4988
  emits: ['update:modelValue', 'close', 'portal-fulfilled', 'visible-change', 'ok', 'cancel'],
4573
- props: props$B,
4989
+ props: props$C,
4574
4990
  setup(props, {
4575
4991
  slots,
4576
4992
  emit,
@@ -4797,6 +5213,10 @@ const ModalView = /* @__PURE__ */ defineComponent({
4797
5213
  expose({
4798
5214
  isActive,
4799
5215
  // for portal
5216
+ toggle(v) {
5217
+ v = typeof v === 'boolean' ? v : !isActive.value;
5218
+ isActive.value = v;
5219
+ },
4800
5220
  resetOrigin
4801
5221
  });
4802
5222
  return () => {
@@ -4887,7 +5307,7 @@ const create$2 = (mode) => (options) => {
4887
5307
  // 当组件内使用emit('close'),避免重复触发
4888
5308
  onClose: null
4889
5309
  });
4890
- leaf.wrapper.isActive = true;
5310
+ leaf.wrapper.toggle?.(true);
4891
5311
  return leaf;
4892
5312
  };
4893
5313
  const destroy$2 = () => Modal.destroy();
@@ -4905,7 +5325,7 @@ const modal$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
4905
5325
  warning: warning$1
4906
5326
  }, Symbol.toStringTag, { value: 'Module' }));
4907
5327
 
4908
- const props$A = {
5328
+ const props$B = {
4909
5329
  mode: {
4910
5330
  type: String,
4911
5331
  validator: (v) => /(alert|operation)/.test(v),
@@ -4967,11 +5387,11 @@ const props$A = {
4967
5387
 
4968
5388
  /** @jsxImportSource vue */
4969
5389
 
4970
- const COMPONENT_NAME$G = 'vc-modal';
5390
+ const COMPONENT_NAME$I = 'vc-modal';
4971
5391
  const MModalView = /* @__PURE__ */ defineComponent({
4972
- name: COMPONENT_NAME$G,
5392
+ name: COMPONENT_NAME$I,
4973
5393
  emits: ['update:modelValue', 'portal-fulfilled', 'close', 'ok', 'cancel'],
4974
- props: props$A,
5394
+ props: props$B,
4975
5395
  setup(props, {
4976
5396
  slots,
4977
5397
  emit,
@@ -5144,7 +5564,7 @@ const modal = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5144
5564
  operation
5145
5565
  }, Symbol.toStringTag, { value: 'Module' }));
5146
5566
 
5147
- const props$z = {
5567
+ const props$A = {
5148
5568
  title: [String, Function],
5149
5569
  content: [String, Function],
5150
5570
  // 单位ms
@@ -5174,40 +5594,31 @@ const props$z = {
5174
5594
 
5175
5595
  /** @jsxImportSource vue */
5176
5596
 
5177
- const COMPONENT_NAME$F = 'vc-notice';
5597
+ const COMPONENT_NAME$H = 'vc-notice';
5178
5598
  const NoticeView = /* @__PURE__ */ defineComponent({
5179
- name: COMPONENT_NAME$F,
5180
- props: props$z,
5599
+ name: COMPONENT_NAME$H,
5600
+ props: props$A,
5181
5601
  emits: ['portal-fulfilled', 'close', 'before-close'],
5182
5602
  setup(props, {
5183
- emit
5603
+ emit,
5604
+ expose
5184
5605
  }) {
5185
5606
  const instance = getCurrentInstance();
5186
5607
  const isActive = ref(false);
5187
5608
  const currentTitle = ref();
5188
5609
  const currentContent = ref();
5610
+ let timer;
5611
+ const setDuration = v => {
5612
+ timer && clearTimeout(timer);
5613
+ if (v === 0) return;
5614
+ timer = setTimeout(() => isActive.value = false, v);
5615
+ };
5189
5616
  const setTitle = v => {
5190
5617
  currentTitle.value = v;
5191
5618
  };
5192
5619
  const setContent = v => {
5193
5620
  currentContent.value = v;
5194
5621
  };
5195
- watch(() => props.title, setTitle, {
5196
- immediate: true
5197
- });
5198
- watch(() => props.content, setContent, {
5199
- immediate: true
5200
- });
5201
- let timer;
5202
- onMounted(() => {
5203
- isActive.value = true;
5204
- if (props.duration !== 0) {
5205
- timer = setTimeout(() => isActive.value = false, props.duration);
5206
- }
5207
- });
5208
- onUnmounted(() => {
5209
- timer && clearTimeout(timer);
5210
- });
5211
5622
 
5212
5623
  // 兼容Portal设计
5213
5624
  const handleRemove = () => {
@@ -5227,6 +5638,27 @@ const NoticeView = /* @__PURE__ */ defineComponent({
5227
5638
  isActive.value = false;
5228
5639
  }
5229
5640
  };
5641
+ watch(() => props.title, setTitle, {
5642
+ immediate: true
5643
+ });
5644
+ watch(() => props.content, setContent, {
5645
+ immediate: true
5646
+ });
5647
+ onMounted(() => {
5648
+ isActive.value = true;
5649
+ setDuration(props.duration);
5650
+ });
5651
+ onUnmounted(() => {
5652
+ timer && clearTimeout(timer);
5653
+ });
5654
+ const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
5655
+ pre[key] = handleRemove;
5656
+ return pre;
5657
+ }, {
5658
+ setContent,
5659
+ setDuration
5660
+ });
5661
+ expose(exposes);
5230
5662
  return () => {
5231
5663
  return createVNode("div", {
5232
5664
  "class": ['vc-notice', {
@@ -5337,7 +5769,7 @@ const Notice$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5337
5769
 
5338
5770
  const MNotice = Notice$1;
5339
5771
 
5340
- const props$y = {
5772
+ const props$z = {
5341
5773
  tag: {
5342
5774
  type: String,
5343
5775
  default: "div"
@@ -5346,10 +5778,10 @@ const props$y = {
5346
5778
 
5347
5779
  /** @jsxImportSource vue */
5348
5780
 
5349
- const COMPONENT_NAME$E = 'vc-option';
5781
+ const COMPONENT_NAME$G = 'vc-option';
5350
5782
  const Option = /* @__PURE__ */ defineComponent({
5351
- name: COMPONENT_NAME$E,
5352
- props: props$y,
5783
+ name: COMPONENT_NAME$G,
5784
+ props: props$z,
5353
5785
  setup(props, {
5354
5786
  slots
5355
5787
  }) {
@@ -5363,7 +5795,7 @@ const Option = /* @__PURE__ */ defineComponent({
5363
5795
 
5364
5796
  const MOption = Option;
5365
5797
 
5366
- const props$x = {
5798
+ const props$y = {
5367
5799
  tag: {
5368
5800
  type: String,
5369
5801
  default: "div"
@@ -5372,10 +5804,10 @@ const props$x = {
5372
5804
 
5373
5805
  /** @jsxImportSource vue */
5374
5806
 
5375
- const COMPONENT_NAME$D = 'vc-page';
5807
+ const COMPONENT_NAME$F = 'vc-page';
5376
5808
  const Page = /* @__PURE__ */ defineComponent({
5377
- name: COMPONENT_NAME$D,
5378
- props: props$x,
5809
+ name: COMPONENT_NAME$F,
5810
+ props: props$y,
5379
5811
  setup(props, {
5380
5812
  slots
5381
5813
  }) {
@@ -5389,7 +5821,7 @@ const Page = /* @__PURE__ */ defineComponent({
5389
5821
 
5390
5822
  const MPage = Page;
5391
5823
 
5392
- const props$w = {
5824
+ const props$x = {
5393
5825
  tag: {
5394
5826
  type: String,
5395
5827
  default: "div"
@@ -5398,10 +5830,10 @@ const props$w = {
5398
5830
 
5399
5831
  /** @jsxImportSource vue */
5400
5832
 
5401
- const COMPONENT_NAME$C = 'vc-picker';
5833
+ const COMPONENT_NAME$E = 'vc-picker';
5402
5834
  const Picker = /* @__PURE__ */ defineComponent({
5403
- name: COMPONENT_NAME$C,
5404
- props: props$w,
5835
+ name: COMPONENT_NAME$E,
5836
+ props: props$x,
5405
5837
  setup(props, {
5406
5838
  slots
5407
5839
  }) {
@@ -5415,7 +5847,7 @@ const Picker = /* @__PURE__ */ defineComponent({
5415
5847
 
5416
5848
  const MPicker = Picker;
5417
5849
 
5418
- const props$v = {
5850
+ const props$w = {
5419
5851
  tag: {
5420
5852
  type: String,
5421
5853
  default: "div"
@@ -5424,10 +5856,10 @@ const props$v = {
5424
5856
 
5425
5857
  /** @jsxImportSource vue */
5426
5858
 
5427
- const COMPONENT_NAME$B = 'vc-popconfirm';
5859
+ const COMPONENT_NAME$D = 'vc-popconfirm';
5428
5860
  const Popconfirm = /* @__PURE__ */ defineComponent({
5429
- name: COMPONENT_NAME$B,
5430
- props: props$v,
5861
+ name: COMPONENT_NAME$D,
5862
+ props: props$w,
5431
5863
  setup(props, {
5432
5864
  slots
5433
5865
  }) {
@@ -5441,7 +5873,7 @@ const Popconfirm = /* @__PURE__ */ defineComponent({
5441
5873
 
5442
5874
  const MPopconfirm = Popconfirm;
5443
5875
 
5444
- const props$u = {
5876
+ const props$v = {
5445
5877
  modelValue: Boolean,
5446
5878
  animation: String,
5447
5879
  placement: {
@@ -5520,7 +5952,7 @@ const wrapperKeys = [
5520
5952
  "autoWidth",
5521
5953
  "always"
5522
5954
  ];
5523
- const props$t = {
5955
+ const props$u = {
5524
5956
  trigger: {
5525
5957
  type: String,
5526
5958
  default: "hover",
@@ -5538,7 +5970,7 @@ const props$t = {
5538
5970
  type: Boolean,
5539
5971
  default: true
5540
5972
  },
5541
- ...pick(props$u, wrapperKeys)
5973
+ ...pick(props$v, wrapperKeys)
5542
5974
  };
5543
5975
 
5544
5976
  const EXTRA_DISTANCE = 4;
@@ -5799,10 +6231,10 @@ const usePos = () => {
5799
6231
  function _isSlot(s) {
5800
6232
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !isVNode(s);
5801
6233
  }
5802
- const COMPONENT_NAME$A = 'vc-popover-wrapper';
6234
+ const COMPONENT_NAME$C = 'vc-popover-wrapper';
5803
6235
  const PopoverWrapper = /* @__PURE__ */ defineComponent({
5804
- name: COMPONENT_NAME$A,
5805
- props: props$u,
6236
+ name: COMPONENT_NAME$C,
6237
+ props: props$v,
5806
6238
  emits: ['portal-fulfilled', 'close'],
5807
6239
  setup(props, {
5808
6240
  emit,
@@ -6012,7 +6444,11 @@ const PopoverWrapper = /* @__PURE__ */ defineComponent({
6012
6444
  props.alone && props.hover && removeEvents();
6013
6445
  });
6014
6446
  expose({
6015
- isActive
6447
+ isActive,
6448
+ toggle(v) {
6449
+ v = typeof v === 'boolean' ? v : !isActive.value;
6450
+ isActive.value = v;
6451
+ }
6016
6452
  });
6017
6453
  return () => {
6018
6454
  let _slot;
@@ -6052,10 +6488,10 @@ const PopoverPortal = new Portal(PopoverWrapper);
6052
6488
 
6053
6489
  /** @jsxImportSource vue */
6054
6490
 
6055
- const COMPONENT_NAME$z = 'vc-popover';
6491
+ const COMPONENT_NAME$B = 'vc-popover';
6056
6492
  const Popover = /* @__PURE__ */ defineComponent({
6057
- name: COMPONENT_NAME$z,
6058
- props: props$t,
6493
+ name: COMPONENT_NAME$B,
6494
+ props: props$u,
6059
6495
  emits: ['update:modelValue', 'visible-change', 'ready', 'close'],
6060
6496
  open: PopoverPortal.popup.bind(PopoverPortal),
6061
6497
  setup(props, {
@@ -6149,7 +6585,7 @@ const Popover = /* @__PURE__ */ defineComponent({
6149
6585
  portalClass
6150
6586
  });
6151
6587
  } else if (popperInstance && popperInstance.wrapper) {
6152
- popperInstance.wrapper.isActive = false;
6588
+ popperInstance.wrapper.toggle(false);
6153
6589
  }
6154
6590
  };
6155
6591
  watch(() => props.modelValue, v => {
@@ -6192,7 +6628,7 @@ const Popover = /* @__PURE__ */ defineComponent({
6192
6628
 
6193
6629
  const MPopover = Popover;
6194
6630
 
6195
- const props$s = {
6631
+ const props$t = {
6196
6632
  tag: {
6197
6633
  type: String,
6198
6634
  default: "div"
@@ -6201,10 +6637,10 @@ const props$s = {
6201
6637
 
6202
6638
  /** @jsxImportSource vue */
6203
6639
 
6204
- const COMPONENT_NAME$y = 'vc-popup';
6640
+ const COMPONENT_NAME$A = 'vc-popup';
6205
6641
  const Popup = /* @__PURE__ */ defineComponent({
6206
- name: COMPONENT_NAME$y,
6207
- props: props$s,
6642
+ name: COMPONENT_NAME$A,
6643
+ props: props$t,
6208
6644
  setup(props, {
6209
6645
  slots
6210
6646
  }) {
@@ -6220,7 +6656,7 @@ const MPopup = Popup;
6220
6656
 
6221
6657
  const MPortal = Portal;
6222
6658
 
6223
- const props$r = {
6659
+ const props$s = {
6224
6660
  tag: {
6225
6661
  type: String,
6226
6662
  default: "div"
@@ -6229,10 +6665,10 @@ const props$r = {
6229
6665
 
6230
6666
  /** @jsxImportSource vue */
6231
6667
 
6232
- const COMPONENT_NAME$x = 'vc-print';
6668
+ const COMPONENT_NAME$z = 'vc-print';
6233
6669
  const Print = /* @__PURE__ */ defineComponent({
6234
- name: COMPONENT_NAME$x,
6235
- props: props$r,
6670
+ name: COMPONENT_NAME$z,
6671
+ props: props$s,
6236
6672
  setup(props, {
6237
6673
  slots
6238
6674
  }) {
@@ -6246,7 +6682,7 @@ const Print = /* @__PURE__ */ defineComponent({
6246
6682
 
6247
6683
  const MPrint = Print;
6248
6684
 
6249
- const props$q = {
6685
+ const props$r = {
6250
6686
  tag: {
6251
6687
  type: String,
6252
6688
  default: "div"
@@ -6255,10 +6691,10 @@ const props$q = {
6255
6691
 
6256
6692
  /** @jsxImportSource vue */
6257
6693
 
6258
- const COMPONENT_NAME$w = 'vc-progress';
6694
+ const COMPONENT_NAME$y = 'vc-progress';
6259
6695
  const Progress = /* @__PURE__ */ defineComponent({
6260
- name: COMPONENT_NAME$w,
6261
- props: props$q,
6696
+ name: COMPONENT_NAME$y,
6697
+ props: props$r,
6262
6698
  setup(props, {
6263
6699
  slots
6264
6700
  }) {
@@ -6272,7 +6708,7 @@ const Progress = /* @__PURE__ */ defineComponent({
6272
6708
 
6273
6709
  const MProgress = Progress;
6274
6710
 
6275
- const props$p = {
6711
+ const props$q = {
6276
6712
  tag: {
6277
6713
  type: String,
6278
6714
  default: "div"
@@ -6281,10 +6717,10 @@ const props$p = {
6281
6717
 
6282
6718
  /** @jsxImportSource vue */
6283
6719
 
6284
- const COMPONENT_NAME$v = 'vc-radio';
6720
+ const COMPONENT_NAME$x = 'vc-radio';
6285
6721
  const Radio = /* @__PURE__ */ defineComponent({
6286
- name: COMPONENT_NAME$v,
6287
- props: props$p,
6722
+ name: COMPONENT_NAME$x,
6723
+ props: props$q,
6288
6724
  setup(props, {
6289
6725
  slots
6290
6726
  }) {
@@ -6298,7 +6734,7 @@ const Radio = /* @__PURE__ */ defineComponent({
6298
6734
 
6299
6735
  const MRadio = Radio;
6300
6736
 
6301
- const props$o = {
6737
+ const props$p = {
6302
6738
  tag: {
6303
6739
  type: String,
6304
6740
  default: "div"
@@ -6307,10 +6743,10 @@ const props$o = {
6307
6743
 
6308
6744
  /** @jsxImportSource vue */
6309
6745
 
6310
- const COMPONENT_NAME$u = 'vc-rate';
6746
+ const COMPONENT_NAME$w = 'vc-rate';
6311
6747
  const Rate = /* @__PURE__ */ defineComponent({
6312
- name: COMPONENT_NAME$u,
6313
- props: props$o,
6748
+ name: COMPONENT_NAME$w,
6749
+ props: props$p,
6314
6750
  setup(props, {
6315
6751
  slots
6316
6752
  }) {
@@ -6324,7 +6760,7 @@ const Rate = /* @__PURE__ */ defineComponent({
6324
6760
 
6325
6761
  const MRate = Rate;
6326
6762
 
6327
- const props$n = {
6763
+ const props$o = {
6328
6764
  data: {
6329
6765
  type: Array,
6330
6766
  default: () => []
@@ -6375,7 +6811,7 @@ const props$n = {
6375
6811
  renderRefresh: Function
6376
6812
  };
6377
6813
 
6378
- const props$m = {
6814
+ const props$n = {
6379
6815
  vertical: Boolean,
6380
6816
  wrapperSize: {
6381
6817
  type: Number,
@@ -6430,7 +6866,7 @@ const barKeys$1 = [
6430
6866
  "thumbStyle",
6431
6867
  "thumbClass"
6432
6868
  ];
6433
- const props$l = {
6869
+ const props$m = {
6434
6870
  // 如果存在滚动条宽度为false, 不存在则为true
6435
6871
  // 为false的情况下才能使用track-offset
6436
6872
  native: {
@@ -6461,7 +6897,7 @@ const props$l = {
6461
6897
  scrollX: Number,
6462
6898
  scrollY: Number,
6463
6899
  fit: Boolean,
6464
- ...pick(props$m, barKeys$1)
6900
+ ...pick(props$n, barKeys$1)
6465
6901
  };
6466
6902
 
6467
6903
  const barKeys = [
@@ -6476,7 +6912,7 @@ const barKeys = [
6476
6912
  "autoResize",
6477
6913
  "native"
6478
6914
  ];
6479
- const props$k = {
6915
+ const props$l = {
6480
6916
  tag: {
6481
6917
  type: String,
6482
6918
  default: "div"
@@ -6509,13 +6945,13 @@ const props$k = {
6509
6945
  type: Boolean,
6510
6946
  default: true
6511
6947
  },
6512
- barTo: props$l.to,
6513
- ...pick(props$l, barKeys)
6948
+ barTo: props$m.to,
6949
+ ...pick(props$m, barKeys)
6514
6950
  };
6515
6951
 
6516
6952
  /** @jsxImportSource vue */
6517
6953
 
6518
- const COMPONENT_NAME$t = 'vc-scroller-track';
6954
+ const COMPONENT_NAME$v = 'vc-scroller-track';
6519
6955
  const BAR_MAP = {
6520
6956
  vertical: {
6521
6957
  scroll: 'scrollTop',
@@ -6535,8 +6971,8 @@ const BAR_MAP = {
6535
6971
  }
6536
6972
  };
6537
6973
  const Track = /* @__PURE__ */ defineComponent({
6538
- name: COMPONENT_NAME$t,
6539
- props: props$m,
6974
+ name: COMPONENT_NAME$v,
6975
+ props: props$n,
6540
6976
  emits: ['change'],
6541
6977
  setup(props, {
6542
6978
  emit,
@@ -6721,10 +7157,10 @@ const Track = /* @__PURE__ */ defineComponent({
6721
7157
 
6722
7158
  /** @jsxImportSource vue */
6723
7159
 
6724
- const COMPONENT_NAME$s = 'vc-scroller-bar';
7160
+ const COMPONENT_NAME$u = 'vc-scroller-bar';
6725
7161
  const Bar = /* @__PURE__ */ defineComponent({
6726
- name: COMPONENT_NAME$s,
6727
- props: props$l,
7162
+ name: COMPONENT_NAME$u,
7163
+ props: props$m,
6728
7164
  emits: ['change'],
6729
7165
  setup(props, {
6730
7166
  emit,
@@ -6937,7 +7373,7 @@ const useScroller = (expose) => {
6937
7373
 
6938
7374
  /** @jsxImportSource vue */
6939
7375
 
6940
- const COMPONENT_NAME$r = 'vc-scroller';
7376
+ const COMPONENT_NAME$t = 'vc-scroller';
6941
7377
 
6942
7378
  /**
6943
7379
  * 作为备选方案,目前推荐使用ScrollerWheel
@@ -6948,8 +7384,8 @@ const COMPONENT_NAME$r = 'vc-scroller';
6948
7384
  * 2. 增加了一层嵌套
6949
7385
  */
6950
7386
  const Scroller = /* @__PURE__ */ defineComponent({
6951
- name: COMPONENT_NAME$r,
6952
- props: props$k,
7387
+ name: COMPONENT_NAME$t,
7388
+ props: props$l,
6953
7389
  emits: ['scroll'],
6954
7390
  setup(props, {
6955
7391
  slots,
@@ -7009,7 +7445,7 @@ const Scroller = /* @__PURE__ */ defineComponent({
7009
7445
 
7010
7446
  /** @jsxImportSource vue */
7011
7447
 
7012
- const COMPONENT_NAME$q = 'vc-scroller-wheel';
7448
+ const COMPONENT_NAME$s = 'vc-scroller-wheel';
7013
7449
 
7014
7450
  /**
7015
7451
  * 为减少一层嵌套,为去除滚动bar的抖动,使用wheel模拟
@@ -7031,8 +7467,8 @@ const COMPONENT_NAME$q = 'vc-scroller-wheel';
7031
7467
  * 设置scrollTop不会reflow和repaint,不需要考虑transfrom来改变content(transform也只在draw完成)
7032
7468
  */
7033
7469
  const ScrollerWheel = /* @__PURE__ */ defineComponent({
7034
- name: COMPONENT_NAME$q,
7035
- props: props$k,
7470
+ name: COMPONENT_NAME$s,
7471
+ props: props$l,
7036
7472
  emits: ['scroll'],
7037
7473
  setup(props, {
7038
7474
  slots,
@@ -7136,9 +7572,9 @@ const ScrollerWheel = /* @__PURE__ */ defineComponent({
7136
7572
 
7137
7573
  /** @jsxImportSource vue */
7138
7574
 
7139
- const COMPONENT_NAME$p = 'vc-recycle-list-scroll-state';
7575
+ const COMPONENT_NAME$r = 'vc-recycle-list-scroll-state';
7140
7576
  const ScrollState = /* @__PURE__ */ defineComponent({
7141
- name: COMPONENT_NAME$p,
7577
+ name: COMPONENT_NAME$r,
7142
7578
  setup(_, {
7143
7579
  slots
7144
7580
  }) {
@@ -7209,7 +7645,7 @@ const STATUS_MAP = {
7209
7645
  }
7210
7646
  };
7211
7647
 
7212
- const props$j = {
7648
+ const props$k = {
7213
7649
  inverted: {
7214
7650
  type: Boolean,
7215
7651
  default: false
@@ -7268,13 +7704,13 @@ const useDirectionKeys = () => {
7268
7704
 
7269
7705
  /** @jsxImportSource vue */
7270
7706
 
7271
- const COMPONENT_NAME$o = 'vc-recycle-list-container';
7707
+ const COMPONENT_NAME$q = 'vc-recycle-list-container';
7272
7708
 
7273
7709
  // TODO: 抽离
7274
7710
  const transformKey = $.prefixStyle('transform').camel;
7275
7711
  const Container = /* @__PURE__ */ defineComponent({
7276
- name: COMPONENT_NAME$o,
7277
- props: props$j,
7712
+ name: COMPONENT_NAME$q,
7713
+ props: props$k,
7278
7714
  emits: ['refresh'],
7279
7715
  setup(props, {
7280
7716
  slots
@@ -7371,16 +7807,16 @@ const Container = /* @__PURE__ */ defineComponent({
7371
7807
 
7372
7808
  /** @jsxImportSource vue */
7373
7809
 
7374
- const COMPONENT_NAME$n = 'vc-recycle-list-item';
7810
+ const COMPONENT_NAME$p = 'vc-recycle-list-item';
7375
7811
  const Item = /* @__PURE__ */ defineComponent({
7376
- name: COMPONENT_NAME$n,
7812
+ name: COMPONENT_NAME$p,
7377
7813
  props: {
7378
7814
  vertical: {
7379
7815
  type: Boolean,
7380
7816
  default: true
7381
7817
  }
7382
7818
  },
7383
- emits: ['resize'],
7819
+ emits: ['resize', 'change'],
7384
7820
  setup(_, {
7385
7821
  emit,
7386
7822
  slots
@@ -7392,9 +7828,10 @@ const Item = /* @__PURE__ */ defineComponent({
7392
7828
  const handleResize = () => {
7393
7829
  const v = current.value.getBoundingClientRect()[K.size];
7394
7830
  const changed = offsetSize.value != v;
7395
- if (hasInitial && changed) {
7831
+ if (changed) {
7396
7832
  offsetSize.value = v;
7397
- emit('resize');
7833
+ hasInitial && emit('resize', v);
7834
+ emit('change', v);
7398
7835
  }
7399
7836
  hasInitial = true;
7400
7837
  };
@@ -7415,10 +7852,10 @@ const Item = /* @__PURE__ */ defineComponent({
7415
7852
 
7416
7853
  /** @jsxImportSource vue */
7417
7854
 
7418
- const COMPONENT_NAME$m = 'vc-recycle-list';
7855
+ const COMPONENT_NAME$o = 'vc-recycle-list';
7419
7856
  const RecycleList = /* @__PURE__ */ defineComponent({
7420
- name: COMPONENT_NAME$m,
7421
- props: props$n,
7857
+ name: COMPONENT_NAME$o,
7858
+ props: props$o,
7422
7859
  emits: ['scroll'],
7423
7860
  setup(props, {
7424
7861
  slots,
@@ -7962,18 +8399,18 @@ const RecycleList = /* @__PURE__ */ defineComponent({
7962
8399
 
7963
8400
  const MRecycleList = RecycleList;
7964
8401
 
7965
- const props$i = {
8402
+ const props$j = {
7966
8403
  tag: {
7967
8404
  type: String,
7968
8405
  default: "div"
7969
8406
  }
7970
8407
  };
7971
8408
 
7972
- const COMPONENT_NAME$l = "vc-resizer";
8409
+ const COMPONENT_NAME$n = "vc-resizer";
7973
8410
  const Resizer = defineComponent({
7974
- name: COMPONENT_NAME$l,
7975
- props: props$i,
7976
- emit: ["resize"],
8411
+ name: COMPONENT_NAME$n,
8412
+ props: props$j,
8413
+ emit: ["resize", "change"],
7977
8414
  setup(props, { emit, slots }) {
7978
8415
  const width = ref(0);
7979
8416
  const height = ref(0);
@@ -7999,8 +8436,9 @@ const Resizer = defineComponent({
7999
8436
  const widthChanged = width.value != width$;
8000
8437
  heightChanged && (height.value = height$);
8001
8438
  widthChanged && (width.value = width$);
8002
- if (hasInitial && (heightChanged || widthChanged)) {
8003
- emit("resize", currentExposed.value);
8439
+ if (heightChanged || widthChanged) {
8440
+ hasInitial && emit("resize", currentExposed.value);
8441
+ emit("change", currentExposed.value);
8004
8442
  }
8005
8443
  hasInitial = true;
8006
8444
  };
@@ -8027,7 +8465,7 @@ const MResizer = Resizer;
8027
8465
 
8028
8466
  const MScroller = Scroller;
8029
8467
 
8030
- const props$h = {
8468
+ const props$i = {
8031
8469
  tag: {
8032
8470
  type: String,
8033
8471
  default: "div"
@@ -8036,10 +8474,10 @@ const props$h = {
8036
8474
 
8037
8475
  /** @jsxImportSource vue */
8038
8476
 
8039
- const COMPONENT_NAME$k = 'vc-select';
8477
+ const COMPONENT_NAME$m = 'vc-select';
8040
8478
  const Select = /* @__PURE__ */ defineComponent({
8041
- name: COMPONENT_NAME$k,
8042
- props: props$h,
8479
+ name: COMPONENT_NAME$m,
8480
+ props: props$i,
8043
8481
  setup(props, {
8044
8482
  slots
8045
8483
  }) {
@@ -8053,7 +8491,7 @@ const Select = /* @__PURE__ */ defineComponent({
8053
8491
 
8054
8492
  const MSelect = Select;
8055
8493
 
8056
- const props$g = {
8494
+ const props$h = {
8057
8495
  tag: {
8058
8496
  type: String,
8059
8497
  default: "div"
@@ -8062,10 +8500,10 @@ const props$g = {
8062
8500
 
8063
8501
  /** @jsxImportSource vue */
8064
8502
 
8065
- const COMPONENT_NAME$j = 'vc-slider';
8503
+ const COMPONENT_NAME$l = 'vc-slider';
8066
8504
  const Slider = /* @__PURE__ */ defineComponent({
8067
- name: COMPONENT_NAME$j,
8068
- props: props$g,
8505
+ name: COMPONENT_NAME$l,
8506
+ props: props$h,
8069
8507
  setup(props, {
8070
8508
  slots
8071
8509
  }) {
@@ -8079,7 +8517,7 @@ const Slider = /* @__PURE__ */ defineComponent({
8079
8517
 
8080
8518
  const MSlider = Slider;
8081
8519
 
8082
- const props$f = {
8520
+ const props$g = {
8083
8521
  tag: {
8084
8522
  type: String,
8085
8523
  default: "div"
@@ -8088,10 +8526,10 @@ const props$f = {
8088
8526
 
8089
8527
  /** @jsxImportSource vue */
8090
8528
 
8091
- const COMPONENT_NAME$i = 'vc-sort-list';
8529
+ const COMPONENT_NAME$k = 'vc-sort-list';
8092
8530
  const SortList = /* @__PURE__ */ defineComponent({
8093
- name: COMPONENT_NAME$i,
8094
- props: props$f,
8531
+ name: COMPONENT_NAME$k,
8532
+ props: props$g,
8095
8533
  setup(props, {
8096
8534
  slots
8097
8535
  }) {
@@ -8105,7 +8543,7 @@ const SortList = /* @__PURE__ */ defineComponent({
8105
8543
 
8106
8544
  const MSortList = SortList;
8107
8545
 
8108
- const props$e = {
8546
+ const props$f = {
8109
8547
  tag: {
8110
8548
  type: String,
8111
8549
  default: "div"
@@ -8114,10 +8552,10 @@ const props$e = {
8114
8552
 
8115
8553
  /** @jsxImportSource vue */
8116
8554
 
8117
- const COMPONENT_NAME$h = 'vc-steps';
8555
+ const COMPONENT_NAME$j = 'vc-steps';
8118
8556
  const Steps = /* @__PURE__ */ defineComponent({
8119
- name: COMPONENT_NAME$h,
8120
- props: props$e,
8557
+ name: COMPONENT_NAME$j,
8558
+ props: props$f,
8121
8559
  setup(props, {
8122
8560
  slots
8123
8561
  }) {
@@ -8131,7 +8569,7 @@ const Steps = /* @__PURE__ */ defineComponent({
8131
8569
 
8132
8570
  const MSteps = Steps;
8133
8571
 
8134
- const props$d = {
8572
+ const props$e = {
8135
8573
  tag: {
8136
8574
  type: String,
8137
8575
  default: "div"
@@ -8140,10 +8578,10 @@ const props$d = {
8140
8578
 
8141
8579
  /** @jsxImportSource vue */
8142
8580
 
8143
- const COMPONENT_NAME$g = 'vc-switch';
8581
+ const COMPONENT_NAME$i = 'vc-switch';
8144
8582
  const Switch = /* @__PURE__ */ defineComponent({
8145
- name: COMPONENT_NAME$g,
8146
- props: props$d,
8583
+ name: COMPONENT_NAME$i,
8584
+ props: props$e,
8147
8585
  setup(props, {
8148
8586
  slots
8149
8587
  }) {
@@ -8157,7 +8595,7 @@ const Switch = /* @__PURE__ */ defineComponent({
8157
8595
 
8158
8596
  const MSwitch = Switch;
8159
8597
 
8160
- const props$c = {
8598
+ const props$d = {
8161
8599
  tag: {
8162
8600
  type: String,
8163
8601
  default: "div"
@@ -8166,10 +8604,10 @@ const props$c = {
8166
8604
 
8167
8605
  /** @jsxImportSource vue */
8168
8606
 
8169
- const COMPONENT_NAME$f = 'vc-table';
8607
+ const COMPONENT_NAME$h = 'vc-table';
8170
8608
  const Table = /* @__PURE__ */ defineComponent({
8171
- name: COMPONENT_NAME$f,
8172
- props: props$c,
8609
+ name: COMPONENT_NAME$h,
8610
+ props: props$d,
8173
8611
  setup(props, {
8174
8612
  slots
8175
8613
  }) {
@@ -8183,7 +8621,7 @@ const Table = /* @__PURE__ */ defineComponent({
8183
8621
 
8184
8622
  const MTable = Table;
8185
8623
 
8186
- const props$b = {
8624
+ const props$c = {
8187
8625
  type: {
8188
8626
  type: String,
8189
8627
  validator: (v) => /^(line|card)$/.test(v),
@@ -8291,7 +8729,7 @@ const useTabs = (options = {}) => {
8291
8729
  if (!item) return;
8292
8730
  list.value.splice(list.value.indexOf(item.props), 1);
8293
8731
  };
8294
- provide("tabs", {
8732
+ provide("vc-tabs", {
8295
8733
  props,
8296
8734
  currentValue,
8297
8735
  refresh,
@@ -8338,10 +8776,10 @@ const useTabs = (options = {}) => {
8338
8776
 
8339
8777
  /** @jsxImportSource vue */
8340
8778
 
8341
- const COMPONENT_NAME$e = 'vc-tabs';
8779
+ const COMPONENT_NAME$g = 'vc-tabs';
8342
8780
  const Tabs = /* @__PURE__ */ defineComponent({
8343
- name: COMPONENT_NAME$e,
8344
- props: props$b,
8781
+ name: COMPONENT_NAME$g,
8782
+ props: props$c,
8345
8783
  emits: ['update:modelValue', 'change', 'click'],
8346
8784
  setup(props, {
8347
8785
  slots
@@ -8506,7 +8944,7 @@ const Tabs = /* @__PURE__ */ defineComponent({
8506
8944
  }
8507
8945
  });
8508
8946
 
8509
- const props$a = {
8947
+ const props$b = {
8510
8948
  value: {
8511
8949
  type: [String, Number]
8512
8950
  },
@@ -8533,7 +8971,7 @@ const useTabsPane = () => {
8533
8971
  const { props } = instance;
8534
8972
  const currentValue = ref(void 0);
8535
8973
  const isLoaded = ref(false);
8536
- const tabs = inject("tabs", {});
8974
+ const tabs = inject("vc-tabs", {});
8537
8975
  const isActive = computed(() => {
8538
8976
  const state = tabs.currentValue.value === (props.value || currentValue.value);
8539
8977
  if (!isLoaded.value && state) {
@@ -8588,10 +9026,10 @@ const useTabsPane = () => {
8588
9026
 
8589
9027
  /** @jsxImportSource vue */
8590
9028
 
8591
- const COMPONENT_NAME$d = 'vc-tabs-pane';
9029
+ const COMPONENT_NAME$f = 'vc-tabs-pane';
8592
9030
  const TabsPane = /* @__PURE__ */ defineComponent({
8593
- name: COMPONENT_NAME$d,
8594
- props: props$a,
9031
+ name: COMPONENT_NAME$f,
9032
+ props: props$b,
8595
9033
  setup(_, {
8596
9034
  slots
8597
9035
  }) {
@@ -8606,8 +9044,329 @@ const TabsPane = /* @__PURE__ */ defineComponent({
8606
9044
  }
8607
9045
  });
8608
9046
 
8609
- const MTabs = Tabs;
8610
- const MTabsPane = TabsPane;
9047
+ const props$a = {
9048
+ ...props$c,
9049
+ theme: {
9050
+ type: String,
9051
+ default: "light",
9052
+ validator: (v) => /(light|dark)/.test(v)
9053
+ },
9054
+ barStyle: {
9055
+ type: [Object, Array],
9056
+ default: () => ({})
9057
+ },
9058
+ autoAfloatWidth: {
9059
+ type: Boolean,
9060
+ default: true
9061
+ },
9062
+ average: {
9063
+ type: Boolean,
9064
+ default: true
9065
+ },
9066
+ showWrapper: {
9067
+ type: Boolean,
9068
+ default: true
9069
+ },
9070
+ sticky: {
9071
+ type: Boolean,
9072
+ default: false
9073
+ },
9074
+ offsetTop: {
9075
+ type: Number,
9076
+ default: 0
9077
+ },
9078
+ showStep: {
9079
+ type: Boolean,
9080
+ default: false
9081
+ }
9082
+ };
9083
+
9084
+ /** @jsxImportSource vue */
9085
+
9086
+ const COMPONENT_NAME$e = 'vcm-tabs';
9087
+ const MTabs = /* @__PURE__ */ defineComponent({
9088
+ name: COMPONENT_NAME$e,
9089
+ props: props$a,
9090
+ emits: ['update:modelValue', 'change', 'click'],
9091
+ setup(props, {
9092
+ slots
9093
+ }) {
9094
+ const instance = getCurrentInstance();
9095
+ const wrapper = ref(null);
9096
+ const content = ref(null);
9097
+ const scroll = ref(null);
9098
+ const nav = ref(null);
9099
+ const top = ref(0);
9100
+ const isFixed = ref(false);
9101
+ const placeholderH = ref(53);
9102
+ const startX = ref(0);
9103
+ const isTouching = ref(false);
9104
+ const scrollViewW = ref(0); // 滚动容器宽度
9105
+ const scrollContentW = ref(0); // 滚动内容宽度
9106
+ const baseX = ref(0);
9107
+ const isDark = computed(() => {
9108
+ return props.theme === 'dark';
9109
+ });
9110
+ const fixedStyle = computed(() => {
9111
+ return isFixed.value ? {
9112
+ top: `${props.offsetTop}px`
9113
+ } : {};
9114
+ });
9115
+
9116
+ // eslint-disable-next-line prefer-const
9117
+ let tabs;
9118
+
9119
+ // TODO: 找到父层滚动条
9120
+ const handleScroll = throttle(() => {
9121
+ isFixed.value = document.scrollingElement.scrollTop + props.offsetTop > top.value;
9122
+ }, 100);
9123
+ const handleTouchstart = e => {
9124
+ isTouching.value = true;
9125
+ startX.value = e.touches[0].pageX;
9126
+ baseX.value = tabs.scrollOffset.value;
9127
+ };
9128
+ const handleTouchmove = throttle(e => {
9129
+ const touchPageX = e.touches[0].pageX;
9130
+ // 与touchstart时触点位置的距离偏移值,大于0时为触点向右移,反之向左
9131
+ const changedX = touchPageX - startX.value;
9132
+ if (changedX > 0) {
9133
+ if (tabs.scrollOffset.value >= 0) {
9134
+ tabs.scrollOffset.value = 0;
9135
+ return;
9136
+ }
9137
+ } else if (Math.abs(tabs.scrollOffset.value) + scrollViewW.value >= scrollContentW.value) {
9138
+ tabs.scrollOffset.value = -(scrollContentW.value - scrollViewW.value);
9139
+ return;
9140
+ }
9141
+ tabs.scrollOffset.value = baseX.value + touchPageX - startX.value;
9142
+ }, 17);
9143
+ const handleTouchend = () => {
9144
+ isTouching.value = false;
9145
+ // TODO: 惯性滚动、回弹 (体验优化)
9146
+ };
9147
+ const handleStep = flag => {
9148
+ if (!tabs.scrollable.value) return;
9149
+ const moveX = flag * scrollViewW.value;
9150
+ let offsetX = tabs.scrollOffset.value + moveX;
9151
+ if (offsetX < -(scrollContentW.value - scrollViewW.value) || offsetX > 0) {
9152
+ offsetX = flag === -1 ? -(scrollContentW.value - scrollViewW.value) : 0;
9153
+ }
9154
+ tabs.scrollOffset.value = offsetX;
9155
+ };
9156
+
9157
+ /**
9158
+ * 使用Resize时, 切换页面失效,换种方案
9159
+ */
9160
+ const refreshTop = debounce(() => {
9161
+ if (props.sticky) {
9162
+ top.value = content.value.offsetTop - placeholderH.value;
9163
+ isFixed.value = document.scrollingElement.scrollTop + props.offsetTop > top.value;
9164
+ }
9165
+ }, 250, {
9166
+ leading: true,
9167
+ trailing: true
9168
+ });
9169
+
9170
+ /**
9171
+ * 将选中的item滚动至可视区(尽量往中间靠)
9172
+ */
9173
+ const scrollToActive = () => {
9174
+ if (!tabs.scrollable.value) return;
9175
+ const activeEl = instance.vnode.el.querySelector(`.vcm-tabs__item[data-id="${tabs.currentValue.value}"]`);
9176
+ if (!activeEl) return;
9177
+ const contentEl = nav.value;
9178
+ const activeRect = activeEl.getBoundingClientRect();
9179
+ const viewRect = scroll.value.getBoundingClientRect();
9180
+ const contentRect = contentEl.getBoundingClientRect();
9181
+ let offset = 0;
9182
+ if (activeRect.width < viewRect.width) {
9183
+ // targetOffset为最理想的情况下,可以滚动到正中间,此时activeEl距scrollView的左右边距
9184
+ const targetOffset = (viewRect.width - activeRect.width) / 2;
9185
+ // offsetLeft其实等价于activeEl.offsetLeft,
9186
+ // 但是调试时发现这两个值在小数位会有差距,offsetLeft一直是整数,所以还是决定用下面这种方式计算offsetLeft
9187
+ const offsetLeft = activeRect.left - contentRect.left;
9188
+ if (offsetLeft - viewRect.left <= targetOffset) {
9189
+ // 左边距离不足以到正中间的情况
9190
+ offset = 0;
9191
+ } else if (contentRect.right - activeRect.right <= targetOffset) {
9192
+ // 右边距离不足以到正中间的情况
9193
+ offset = viewRect.width - contentRect.width; // 负值
9194
+ } else {
9195
+ offset = targetOffset - offsetLeft; // 可以滚动到正中间的理想情况
9196
+ }
9197
+ }
9198
+ tabs.scrollOffset.value = offset;
9199
+ };
9200
+ const operateDOMScrollEvents = type => {
9201
+ const fn = type === 'add' ? window.addEventListener : window.removeEventListener;
9202
+ fn('scroll', handleScroll);
9203
+ fn('touchstart', handleTouchstart, false);
9204
+ fn('touchmove', handleTouchmove, false);
9205
+ fn('touchend', handleTouchend, false);
9206
+ };
9207
+
9208
+ /**
9209
+ * 处理是否需要滚动
9210
+ */
9211
+ const refreshScroll = () => {
9212
+ const viewEl = scroll.value;
9213
+ scrollViewW.value = viewEl.offsetWidth;
9214
+ scrollContentW.value = nav.value.offsetWidth;
9215
+ if (scrollContentW.value > scrollViewW.value) {
9216
+ operateDOMScrollEvents('remove');
9217
+ operateDOMScrollEvents('add');
9218
+ tabs.scrollable.value = true;
9219
+ } else if (tabs.scrollable.value) {
9220
+ operateDOMScrollEvents('remove');
9221
+ tabs.scrollable.value = false;
9222
+ }
9223
+ tabs.scrollable.value && scrollToActive();
9224
+ };
9225
+
9226
+ /**
9227
+ * 刷新当前标签底下的滑块位置
9228
+ */
9229
+ const refreshAfloat = () => {
9230
+ if (!props.showWrapper) return;
9231
+ nextTick(() => {
9232
+ const index = tabs.getTabIndex(tabs.currentValue.value);
9233
+ if (instance.isUnmounted) return;
9234
+ const items = nav.value.querySelectorAll(`.vcm-tabs__item`);
9235
+ const $ = items[index];
9236
+
9237
+ // 暂时写死42
9238
+ tabs.afloatWidth.value = $ ? isDark.value ? 20 : props.autoAfloatWidth ? $.querySelector('span').offsetWidth : $.offsetWidth : 0;
9239
+ if (!Array.from(items).length) return;
9240
+ let offset = 0;
9241
+ const basicOffset = $ ? ($.offsetWidth - tabs.afloatWidth.value) / 2 : 0;
9242
+ if (index > 0) {
9243
+ for (let i = 0; i < index; i++) {
9244
+ offset += parseFloat(items[i].offsetWidth);
9245
+ }
9246
+ }
9247
+ tabs.afloatOffset.value = offset + basicOffset;
9248
+ refreshScroll();
9249
+ });
9250
+ };
9251
+
9252
+ /**
9253
+ * TODO: 在height: 100%容器内滚动,让其带有粘性
9254
+ * @param type ~
9255
+ */
9256
+ const operateDOMEvents = type => {
9257
+ if (!props.sticky) return;
9258
+ const fn = type === 'add' ? window.addEventListener : window.removeEventListener;
9259
+ fn('scroll', handleScroll);
9260
+ };
9261
+ tabs = useTabs({
9262
+ content,
9263
+ wrapper,
9264
+ refreshAfloat,
9265
+ refreshScroll,
9266
+ scrollToActive
9267
+ });
9268
+ const scrollStyle = computed(() => {
9269
+ return {
9270
+ transition: isTouching.value ? '' : 'transform 300ms ease-in-out',
9271
+ transform: `translate3d(${tabs.scrollOffset.value}px, 0, 0)`
9272
+ };
9273
+ });
9274
+ onMounted(() => {
9275
+ refreshTop();
9276
+ operateDOMEvents('add');
9277
+ nextTick(refreshScroll);
9278
+ });
9279
+ onUpdated(refreshTop);
9280
+ onUnmounted(() => {
9281
+ operateDOMEvents('remove');
9282
+ operateDOMScrollEvents('remove');
9283
+ });
9284
+ watch(() => props.theme, refreshAfloat);
9285
+ watch(() => props.average, refreshAfloat);
9286
+ watch(() => props.showStep, () => nextTick(refreshScroll));
9287
+ return () => {
9288
+ return createVNode("div", {
9289
+ "class": [tabs.classes.value, 'vcm-tabs']
9290
+ }, [props.showWrapper && createVNode("div", {
9291
+ "ref": wrapper,
9292
+ "style": [props.barStyle, fixedStyle.value],
9293
+ "class": [{
9294
+ 'is-fixed': isFixed
9295
+ }, 'vcm-tabs__bar']
9296
+ }, [createVNode("slot", {
9297
+ "name": "prepend"
9298
+ }, null), slots.prepend?.(), props.showStep && tabs.scrollable.value && createVNode("div", {
9299
+ "class": "vcm-tabs__step is-left",
9300
+ "onClick": () => handleStep(1)
9301
+ }, [createVNode(Icon, {
9302
+ "type": "left"
9303
+ }, null)]), createVNode("div", {
9304
+ "ref": scroll,
9305
+ "class": "vcm-tabs__scroll"
9306
+ }, [createVNode("div", {
9307
+ "ref": nav,
9308
+ "style": scrollStyle.value,
9309
+ "class": "vcm-tabs__nav"
9310
+ }, [props.afloat && createVNode("div", {
9311
+ "style": tabs.afloatStyle.value,
9312
+ "class": "vcm-tabs__afloat"
9313
+ }, null), tabs.list.value.map((item, index) => {
9314
+ return createVNode("div", {
9315
+ "key": index,
9316
+ "data-id": item.value,
9317
+ "class": [{
9318
+ 'is-active': (item.value || index) == tabs.currentValue.value,
9319
+ 'is-average': props.average
9320
+ }, 'vcm-tabs__item'],
9321
+ "onClick": () => tabs.handleChange(index)
9322
+ }, [slots.label ? slots.label({
9323
+ it: item,
9324
+ index
9325
+ }) : typeof item.label === 'string' ? createVNode("span", {
9326
+ "innerHTML": item.label
9327
+ }, null) : typeof item.label === 'function' && createVNode(Customer, {
9328
+ "render": item.label,
9329
+ "it": item,
9330
+ "index": index
9331
+ }, null)]);
9332
+ })])]), props.showStep && tabs.scrollable.value && createVNode("div", {
9333
+ "class": "vcm-tabs__step is-right",
9334
+ "onClick": () => handleStep(-1)
9335
+ }, [createVNode(Icon, {
9336
+ "type": "right"
9337
+ }, null)]), slots.append?.()]), isFixed.value && createVNode("div", {
9338
+ "style": {
9339
+ height: `${placeholderH.value}px`
9340
+ },
9341
+ "class": "vcm-tabs__placeholder"
9342
+ }, null), createVNode("div", {
9343
+ "ref": content,
9344
+ "style": tabs.contentStyle.value,
9345
+ "class": "vcm-tabs__content"
9346
+ }, [slots.default?.()])]);
9347
+ };
9348
+ }
9349
+ });
9350
+
9351
+ /** @jsxImportSource vue */
9352
+
9353
+ const COMPONENT_NAME$d = 'vcm-tabs-pane';
9354
+ const MTabsPane = /* @__PURE__ */ defineComponent({
9355
+ name: COMPONENT_NAME$d,
9356
+ props: props$b,
9357
+ setup(_, {
9358
+ slots
9359
+ }) {
9360
+ const tabsPane = useTabsPane();
9361
+ return () => {
9362
+ return createVNode("div", {
9363
+ "class": "vcm-tabs-pane",
9364
+ "style": tabsPane.style.value,
9365
+ "name": tabsPane.currentValue.value
9366
+ }, [tabsPane.isReady && slots.default?.()]);
9367
+ };
9368
+ }
9369
+ });
8611
9370
 
8612
9371
  const props$9 = {
8613
9372
  tag: {
@@ -9031,4 +9790,4 @@ const UploadPicker = /* @__PURE__ */ defineComponent({
9031
9790
 
9032
9791
  const MUploadPicker = UploadPicker;
9033
9792
 
9034
- export { ActionSheet, Alert, Artboard, Button, ButtonGroup, Calendar, Card, Carousel, Cascader, Chart, Checkbox, Clipboard, Collapse, ColorPicker, Countdown, Customer, DatePicker, Debounce, Divider, Drawer, Dropdown, Editor, Expand, Form, FormItem, Fragment, HTMLToImage, Icon, IconManager, Image, ImageCrop, ImagePreview, ImageProcessing, Input, InputNumber, InputSearch, MList as List, MListItem as ListItem, MActionSheet, MAlert, MArtboard, MButton, MButtonGroup, MCalendar, MCard, MCarousel, MCascader, MChart, MCheckbox, MClipboard, MCollapse, MColorPicker, MCountdown, MCustomer, MDatePicker, Debounce as MDebounce, MDivider, MDrawer, MDropdown, MEditor, MExpand, MForm, MFormItem, MFragment, MHTMLToImage, MIcon, MImage, MImageCrop, MImagePreview, MImageProcessing, MInput, MInputNumber, MInputSearch, MList, MListItem, MMarquee, MMessage, modal as MModal, MModalView, MNotice, MOption, MPage, MPicker, MPopconfirm, MPopover, MPopup, MPortal, MPrint, MProgress, MRadio, MRate, MRecycleList, MResizer, MScroller, MSelect, MSlider, MSortList, MSpin, MSteps, MSwitch, MTable, MTabs, MTabsPane, MTag, MText, MTextarea, MTimePicker, MTimeline, MToast$1 as MToast, MToastView, MTouch, MTransition, MTransitionCollapse, MTransitionFade, MTransitionScale, MTransitionSlide, MTransitionZoom, MTree, MUpload, MUploadPicker, Marquee, Message$1 as Message, MessageView, modal$1 as Modal, ModalView, Notice$1 as Notice, NoticeView, Option, Page, Picker, Popconfirm, Popover, Popup, Portal, PortalView, Print, Progress, Radio, Rate, RecycleList, Resizer, Scroller, ScrollerWheel, Select, Slider, SortList, Spin, Steps, Switch, Table, Tabs, TabsPane, Tag, Text, Textarea, Theme, ThemeImage, ThemeText, ThemeView, TimePicker, Timeline, Toast, ToastView, Touch, Transition, TransitionCollapse, TransitionFade, TransitionScale, TransitionSlide, TransitionZoom, Tree, Upload, UploadPicker, VcError, VcInstance };
9793
+ export { ActionSheet, Alert, Artboard, Button, ButtonGroup, Calendar, Card, Carousel, Cascader, Chart, Checkbox, Clipboard, Collapse, CollapseItem, ColorPicker, Countdown, Customer, DatePicker, Debounce, Divider, drawer as Drawer, DrawerView, Dropdown, Editor, Expand, Form, FormItem, Fragment, HTMLToImage, Icon, IconManager, Image, ImageCrop, ImagePreview, ImageProcessing, Input, InputNumber, InputSearch, MList as List, MListItem as ListItem, MActionSheet, MAlert, MArtboard, MButton, MButtonGroup, MCalendar, MCard, MCarousel, MCascader, MChart, MCheckbox, MClipboard, MCollapse, MCollapseItem, MColorPicker, MCountdown, MCustomer, MDatePicker, Debounce as MDebounce, MDivider, MDrawerView, MDropdown, MEditor, MExpand, MForm, MFormItem, MFragment, MHTMLToImage, MIcon, MImage, MImageCrop, MImagePreview, MImageProcessing, MInput, MInputNumber, MInputSearch, MList, MListItem, MMarquee, MMessage, modal as MModal, MModalView, MNotice, MOption, MPage, MPicker, MPopconfirm, MPopover, MPopup, MPortal, MPrint, MProgress, MRadio, MRate, MRecycleList, MResizer, MScroller, MSelect, MSlider, MSortList, MSpin, MSteps, MSwitch, MTable, MTabs, MTabsPane, MTag, MText, MTextarea, MTimePicker, MTimeline, MToast$1 as MToast, MToastView, MTouch, MTransition, MTransitionCollapse, MTransitionFade, MTransitionScale, MTransitionSlide, MTransitionZoom, MTree, MUpload, MUploadPicker, Marquee, Message$1 as Message, MessageView, modal$1 as Modal, ModalView, Notice$1 as Notice, NoticeView, Option, Page, Picker, Popconfirm, Popover, Popup, Portal, PortalView, Print, Progress, Radio, Rate, RecycleList, Resizer, Scroller, ScrollerWheel, Select, Slider, SortList, Spin, Steps, Switch, Table, Tabs, TabsPane, Tag, Text, Textarea, Theme, ThemeImage, ThemeText, ThemeView, TimePicker, Timeline, Toast, ToastView, Touch, Transition, TransitionCollapse, TransitionFade, TransitionScale, TransitionSlide, TransitionZoom, Tree, Upload, UploadPicker, VcError, VcInstance };