@deot/vc-components 1.0.5 → 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.cjs CHANGED
@@ -6,10 +6,10 @@ const vue = require('vue');
6
6
  const lodashEs = require('lodash-es');
7
7
  const helperResize = require('@deot/helper-resize');
8
8
  const Utils = require('@deot/helper-utils');
9
- const helperValidator = require('@deot/helper-validator');
10
- const vcShared = require('@deot/vc-shared');
11
9
  const $ = require('@deot/helper-dom');
10
+ const vcShared = require('@deot/vc-shared');
12
11
  const vcHooks = require('@deot/vc-hooks');
12
+ const helperValidator = require('@deot/helper-validator');
13
13
  const helperCache = require('@deot/helper-cache');
14
14
  const helperScheduler = require('@deot/helper-scheduler');
15
15
  const helperWheel = require('@deot/helper-wheel');
@@ -80,7 +80,7 @@ class Instance {
80
80
  }
81
81
  const VcInstance = new Instance();
82
82
 
83
- const props$1h = {
83
+ const props$1j = {
84
84
  tag: {
85
85
  type: String,
86
86
  default: "div"
@@ -89,10 +89,10 @@ const props$1h = {
89
89
 
90
90
  /** @jsxImportSource vue */
91
91
 
92
- const COMPONENT_NAME$1x = 'vc-action-sheet';
92
+ const COMPONENT_NAME$1A = 'vc-action-sheet';
93
93
  const ActionSheet = /* @__PURE__ */ vue.defineComponent({
94
- name: COMPONENT_NAME$1x,
95
- props: props$1h,
94
+ name: COMPONENT_NAME$1A,
95
+ props: props$1j,
96
96
  setup(props, {
97
97
  slots
98
98
  }) {
@@ -106,7 +106,7 @@ const ActionSheet = /* @__PURE__ */ vue.defineComponent({
106
106
 
107
107
  const MActionSheet = ActionSheet;
108
108
 
109
- const props$1g = {
109
+ const props$1i = {
110
110
  modelValue: {
111
111
  type: Boolean,
112
112
  default: true
@@ -133,7 +133,7 @@ const props$1g = {
133
133
  }
134
134
  };
135
135
 
136
- const props$1f = {
136
+ const props$1h = {
137
137
  type: String,
138
138
  inherit: {
139
139
  type: Boolean,
@@ -186,7 +186,7 @@ class Manager {
186
186
  icons = await this.parser(data, url);
187
187
  try {
188
188
  window.localStorage.setItem(key, JSON.stringify(icons));
189
- } catch (e) {
189
+ } catch {
190
190
  setTimeout(() => {
191
191
  this.clearResource();
192
192
  window.localStorage.setItem(key, JSON.stringify(icons));
@@ -278,10 +278,10 @@ const IconManager = new Manager();
278
278
 
279
279
  /** @jsxImportSource vue */
280
280
 
281
- const COMPONENT_NAME$1w = 'vc-icon';
281
+ const COMPONENT_NAME$1z = 'vc-icon';
282
282
  const Icon = /* @__PURE__ */ vue.defineComponent({
283
- name: COMPONENT_NAME$1w,
284
- props: props$1f,
283
+ name: COMPONENT_NAME$1z,
284
+ props: props$1h,
285
285
  setup(props) {
286
286
  const viewBox = vue.ref('0 0 1024 1024');
287
287
  const path = vue.ref([]);
@@ -314,7 +314,7 @@ const Icon = /* @__PURE__ */ vue.defineComponent({
314
314
  }
315
315
  });
316
316
 
317
- const props$1e = {
317
+ const props$1g = {
318
318
  /**
319
319
  * 进入/离开持续时间
320
320
  * {enter: 300, leave: 300}
@@ -479,10 +479,10 @@ const useTransition = () => {
479
479
  };
480
480
  };
481
481
 
482
- const COMPONENT_NAME$1v = "vc-transition";
482
+ const COMPONENT_NAME$1y = "vc-transition";
483
483
  const Transition = vue.defineComponent({
484
- name: COMPONENT_NAME$1v,
485
- props: props$1e,
484
+ name: COMPONENT_NAME$1y,
485
+ props: props$1g,
486
486
  // 当不声明emits的情况下,事件存在于attrs中
487
487
  inheritAttrs: false,
488
488
  setup(props, { slots, attrs }) {
@@ -502,10 +502,10 @@ const Transition = vue.defineComponent({
502
502
  }
503
503
  });
504
504
 
505
- const COMPONENT_NAME$1u = "vc-transition-collapse";
505
+ const COMPONENT_NAME$1x = "vc-transition-collapse";
506
506
  const TransitionCollapse = vue.defineComponent({
507
- name: COMPONENT_NAME$1u,
508
- props: props$1e,
507
+ name: COMPONENT_NAME$1x,
508
+ props: props$1g,
509
509
  // 当不声明emits的情况下,事件存在于attrs中
510
510
  inheritAttrs: false,
511
511
  setup(props, { slots, attrs: _attrs }) {
@@ -623,11 +623,11 @@ const TransitionCollapse = vue.defineComponent({
623
623
  }
624
624
  });
625
625
 
626
- const COMPONENT_NAME$1t = "vc-transition-fade";
626
+ const COMPONENT_NAME$1w = "vc-transition-fade";
627
627
  const TransitionFade = vue.defineComponent({
628
- name: COMPONENT_NAME$1t,
628
+ name: COMPONENT_NAME$1w,
629
629
  props: {
630
- ...props$1e,
630
+ ...props$1g,
631
631
  // inheritAttrs必须是false
632
632
  style: {
633
633
  type: Object,
@@ -660,11 +660,11 @@ const TransitionFade = vue.defineComponent({
660
660
  }
661
661
  });
662
662
 
663
- const COMPONENT_NAME$1s = "vc-transition-scale";
663
+ const COMPONENT_NAME$1v = "vc-transition-scale";
664
664
  const TransitionScale = vue.defineComponent({
665
- name: COMPONENT_NAME$1s,
665
+ name: COMPONENT_NAME$1v,
666
666
  props: {
667
- ...props$1e,
667
+ ...props$1g,
668
668
  mode: {
669
669
  type: String,
670
670
  default: "both",
@@ -702,15 +702,15 @@ const TransitionScale = vue.defineComponent({
702
702
  }
703
703
  });
704
704
 
705
- const COMPONENT_NAME$1r = "vc-transition-slide";
705
+ const COMPONENT_NAME$1u = "vc-transition-slide";
706
706
  const TransitionSlide = vue.defineComponent({
707
- name: COMPONENT_NAME$1r,
707
+ name: COMPONENT_NAME$1u,
708
708
  props: {
709
- ...props$1e,
709
+ ...props$1g,
710
710
  mode: {
711
711
  type: String,
712
712
  default: "left",
713
- validator: (v) => /^(left|right|down|up|none)(|-part)$/.test(v)
713
+ validator: (v) => /^(left|right|top|bottom|none)(|-part)$/.test(v)
714
714
  },
715
715
  // inheritAttrs必须是false
716
716
  style: {
@@ -744,11 +744,11 @@ const TransitionSlide = vue.defineComponent({
744
744
  }
745
745
  });
746
746
 
747
- const COMPONENT_NAME$1q = "vc-transition-zoom";
747
+ const COMPONENT_NAME$1t = "vc-transition-zoom";
748
748
  const TransitionZoom = vue.defineComponent({
749
- name: COMPONENT_NAME$1q,
749
+ name: COMPONENT_NAME$1t,
750
750
  props: {
751
- ...props$1e,
751
+ ...props$1g,
752
752
  mode: {
753
753
  type: String,
754
754
  default: "x",
@@ -788,7 +788,7 @@ const TransitionZoom = vue.defineComponent({
788
788
 
789
789
  /** @jsxImportSource vue */
790
790
 
791
- const COMPONENT_NAME$1p = 'vc-alert';
791
+ const COMPONENT_NAME$1s = 'vc-alert';
792
792
 
793
793
  // [color, borderColor, backgroundColor], -> CSS
794
794
  const THEME_MAP = {
@@ -798,8 +798,8 @@ const THEME_MAP = {
798
798
  warning: ['#ffbf00', '#ffe58f', '#fffbe6']
799
799
  };
800
800
  const Alert = /* @__PURE__ */ vue.defineComponent({
801
- name: COMPONENT_NAME$1p,
802
- props: props$1g,
801
+ name: COMPONENT_NAME$1s,
802
+ props: props$1i,
803
803
  setup(props, {
804
804
  slots,
805
805
  emit
@@ -888,7 +888,7 @@ const Alert = /* @__PURE__ */ vue.defineComponent({
888
888
 
889
889
  const MAlert = Alert;
890
890
 
891
- const props$1d = {
891
+ const props$1f = {
892
892
  tag: {
893
893
  type: String,
894
894
  default: "div"
@@ -897,10 +897,10 @@ const props$1d = {
897
897
 
898
898
  /** @jsxImportSource vue */
899
899
 
900
- const COMPONENT_NAME$1o = 'vc-artboard';
900
+ const COMPONENT_NAME$1r = 'vc-artboard';
901
901
  const Artboard = /* @__PURE__ */ vue.defineComponent({
902
- name: COMPONENT_NAME$1o,
903
- props: props$1d,
902
+ name: COMPONENT_NAME$1r,
903
+ props: props$1f,
904
904
  setup(props, {
905
905
  slots
906
906
  }) {
@@ -914,7 +914,7 @@ const Artboard = /* @__PURE__ */ vue.defineComponent({
914
914
 
915
915
  const MArtboard = Artboard;
916
916
 
917
- const props$1c = {
917
+ const props$1e = {
918
918
  size: {
919
919
  type: Number,
920
920
  default: 28
@@ -938,10 +938,10 @@ const props$1c = {
938
938
 
939
939
  /** @jsxImportSource vue */
940
940
 
941
- const COMPONENT_NAME$1n = 'vc-spin';
941
+ const COMPONENT_NAME$1q = 'vc-spin';
942
942
  const Spin = /* @__PURE__ */ vue.defineComponent({
943
- name: COMPONENT_NAME$1n,
944
- props: props$1c,
943
+ name: COMPONENT_NAME$1q,
944
+ props: props$1e,
945
945
  setup(props, {
946
946
  slots
947
947
  }) {
@@ -975,7 +975,7 @@ const Spin = /* @__PURE__ */ vue.defineComponent({
975
975
  }
976
976
  });
977
977
 
978
- const props$1b = {
978
+ const props$1d = {
979
979
  wait: {
980
980
  type: Number,
981
981
  default: 250
@@ -991,10 +991,10 @@ const props$1b = {
991
991
  exclude: RegExp
992
992
  };
993
993
 
994
- const COMPONENT_NAME$1m = "vc-debounce";
994
+ const COMPONENT_NAME$1p = "vc-debounce";
995
995
  const Debounce = vue.defineComponent({
996
- name: COMPONENT_NAME$1m,
997
- props: props$1b,
996
+ name: COMPONENT_NAME$1p,
997
+ props: props$1d,
998
998
  /**
999
999
  * 不声明emits使得事件被透传放入attrs中, 这样可以让所有的事件透传
1000
1000
  * 如事件onClick
@@ -1035,7 +1035,7 @@ const Debounce = vue.defineComponent({
1035
1035
  }
1036
1036
  });
1037
1037
 
1038
- const props$1a = {
1038
+ const props$1c = {
1039
1039
  tag: {
1040
1040
  type: String,
1041
1041
  default: "button"
@@ -1065,18 +1065,18 @@ const props$1a = {
1065
1065
 
1066
1066
  /** @jsxImportSource vue */
1067
1067
 
1068
- const COMPONENT_NAME$1l = 'vc-button';
1068
+ const COMPONENT_NAME$1o = 'vc-button';
1069
1069
  const Button = /* @__PURE__ */ vue.defineComponent({
1070
- name: COMPONENT_NAME$1l,
1070
+ name: COMPONENT_NAME$1o,
1071
1071
  emits: ['click'],
1072
- props: props$1a,
1072
+ props: props$1c,
1073
1073
  setup(props, {
1074
1074
  slots
1075
1075
  }) {
1076
1076
  const vm = vue.getCurrentInstance();
1077
1077
  const hasSlot = vue.ref(true);
1078
1078
  const isLoading = vue.ref(false);
1079
- const group = vue.inject('button-group', {
1079
+ const group = vue.inject('vc-button-group', {
1080
1080
  size: 'medium',
1081
1081
  vertical: false,
1082
1082
  circle: false
@@ -1126,7 +1126,7 @@ const Button = /* @__PURE__ */ vue.defineComponent({
1126
1126
  }
1127
1127
  });
1128
1128
 
1129
- const props$19 = {
1129
+ const props$1b = {
1130
1130
  vertical: {
1131
1131
  type: Boolean,
1132
1132
  default: false
@@ -1147,14 +1147,14 @@ const props$19 = {
1147
1147
 
1148
1148
  /** @jsxImportSource vue */
1149
1149
 
1150
- const COMPONENT_NAME$1k = 'vc-button-group';
1150
+ const COMPONENT_NAME$1n = 'vc-button-group';
1151
1151
  const ButtonGroup = /* @__PURE__ */ vue.defineComponent({
1152
- name: COMPONENT_NAME$1k,
1153
- props: props$19,
1152
+ name: COMPONENT_NAME$1n,
1153
+ props: props$1b,
1154
1154
  setup(props, {
1155
1155
  slots
1156
1156
  }) {
1157
- vue.provide('button-group', props);
1157
+ vue.provide('vc-button-group', props);
1158
1158
  const classes = vue.computed(() => ({
1159
1159
  'is-vertical': props.vertical,
1160
1160
  'is-circle': props.circle,
@@ -1174,7 +1174,7 @@ const ButtonGroup = /* @__PURE__ */ vue.defineComponent({
1174
1174
  const MButton = Button;
1175
1175
  const MButtonGroup = ButtonGroup;
1176
1176
 
1177
- const props$18 = {
1177
+ const props$1a = {
1178
1178
  tag: {
1179
1179
  type: String,
1180
1180
  default: "div"
@@ -1183,10 +1183,10 @@ const props$18 = {
1183
1183
 
1184
1184
  /** @jsxImportSource vue */
1185
1185
 
1186
- const COMPONENT_NAME$1j = 'vc-calendar';
1186
+ const COMPONENT_NAME$1m = 'vc-calendar';
1187
1187
  const Calendar = /* @__PURE__ */ vue.defineComponent({
1188
- name: COMPONENT_NAME$1j,
1189
- props: props$18,
1188
+ name: COMPONENT_NAME$1m,
1189
+ props: props$1a,
1190
1190
  setup(props, {
1191
1191
  slots
1192
1192
  }) {
@@ -1200,7 +1200,7 @@ const Calendar = /* @__PURE__ */ vue.defineComponent({
1200
1200
 
1201
1201
  const MCalendar = Calendar;
1202
1202
 
1203
- const props$17 = {
1203
+ const props$19 = {
1204
1204
  border: {
1205
1205
  type: Boolean,
1206
1206
  default: true
@@ -1223,10 +1223,10 @@ const props$17 = {
1223
1223
 
1224
1224
  /** @jsxImportSource vue */
1225
1225
 
1226
- const COMPONENT_NAME$1i = 'vc-card';
1226
+ const COMPONENT_NAME$1l = 'vc-card';
1227
1227
  const Card = /* @__PURE__ */ vue.defineComponent({
1228
- name: COMPONENT_NAME$1i,
1229
- props: props$17,
1228
+ name: COMPONENT_NAME$1l,
1229
+ props: props$19,
1230
1230
  setup(props, {
1231
1231
  slots
1232
1232
  }) {
@@ -1252,7 +1252,7 @@ const Card = /* @__PURE__ */ vue.defineComponent({
1252
1252
 
1253
1253
  const MCard = Card;
1254
1254
 
1255
- const props$16 = {
1255
+ const props$18 = {
1256
1256
  tag: {
1257
1257
  type: String,
1258
1258
  default: "div"
@@ -1261,10 +1261,10 @@ const props$16 = {
1261
1261
 
1262
1262
  /** @jsxImportSource vue */
1263
1263
 
1264
- const COMPONENT_NAME$1h = 'vc-carousel';
1264
+ const COMPONENT_NAME$1k = 'vc-carousel';
1265
1265
  const Carousel = /* @__PURE__ */ vue.defineComponent({
1266
- name: COMPONENT_NAME$1h,
1267
- props: props$16,
1266
+ name: COMPONENT_NAME$1k,
1267
+ props: props$18,
1268
1268
  setup(props, {
1269
1269
  slots
1270
1270
  }) {
@@ -1278,7 +1278,7 @@ const Carousel = /* @__PURE__ */ vue.defineComponent({
1278
1278
 
1279
1279
  const MCarousel = Carousel;
1280
1280
 
1281
- const props$15 = {
1281
+ const props$17 = {
1282
1282
  tag: {
1283
1283
  type: String,
1284
1284
  default: "div"
@@ -1287,10 +1287,10 @@ const props$15 = {
1287
1287
 
1288
1288
  /** @jsxImportSource vue */
1289
1289
 
1290
- const COMPONENT_NAME$1g = 'vc-cascader';
1290
+ const COMPONENT_NAME$1j = 'vc-cascader';
1291
1291
  const Cascader = /* @__PURE__ */ vue.defineComponent({
1292
- name: COMPONENT_NAME$1g,
1293
- props: props$15,
1292
+ name: COMPONENT_NAME$1j,
1293
+ props: props$17,
1294
1294
  setup(props, {
1295
1295
  slots
1296
1296
  }) {
@@ -1343,7 +1343,7 @@ const EVENTS = [
1343
1343
  "contextmenu"
1344
1344
  ];
1345
1345
 
1346
- const props$14 = {
1346
+ const props$16 = {
1347
1347
  options: Object,
1348
1348
  pluginOptions: Object,
1349
1349
  theme: [String, Object],
@@ -1355,10 +1355,10 @@ const props$14 = {
1355
1355
 
1356
1356
  /** @jsxImportSource vue */
1357
1357
 
1358
- const COMPONENT_NAME$1f = 'vc-chart';
1358
+ const COMPONENT_NAME$1i = 'vc-chart';
1359
1359
  const Chart = /* @__PURE__ */ vue.defineComponent({
1360
- name: COMPONENT_NAME$1f,
1361
- props: props$14,
1360
+ name: COMPONENT_NAME$1i,
1361
+ props: props$16,
1362
1362
  emits: [...EVENTS, 'ready'],
1363
1363
  setup(props, {
1364
1364
  emit,
@@ -1472,7 +1472,7 @@ const Chart = /* @__PURE__ */ vue.defineComponent({
1472
1472
 
1473
1473
  const MChart = Chart;
1474
1474
 
1475
- const props$13 = {
1475
+ const props$15 = {
1476
1476
  tag: {
1477
1477
  type: String,
1478
1478
  default: "div"
@@ -1481,10 +1481,10 @@ const props$13 = {
1481
1481
 
1482
1482
  /** @jsxImportSource vue */
1483
1483
 
1484
- const COMPONENT_NAME$1e = 'vc-checkbox';
1484
+ const COMPONENT_NAME$1h = 'vc-checkbox';
1485
1485
  const Checkbox = /* @__PURE__ */ vue.defineComponent({
1486
- name: COMPONENT_NAME$1e,
1487
- props: props$13,
1486
+ name: COMPONENT_NAME$1h,
1487
+ props: props$15,
1488
1488
  setup(props, {
1489
1489
  slots
1490
1490
  }) {
@@ -1498,7 +1498,7 @@ const Checkbox = /* @__PURE__ */ vue.defineComponent({
1498
1498
 
1499
1499
  const MCheckbox = Checkbox;
1500
1500
 
1501
- const props$12 = {
1501
+ const props$14 = {
1502
1502
  tag: {
1503
1503
  type: String,
1504
1504
  default: "div"
@@ -1507,10 +1507,10 @@ const props$12 = {
1507
1507
 
1508
1508
  /** @jsxImportSource vue */
1509
1509
 
1510
- const COMPONENT_NAME$1d = 'vc-clipboard';
1510
+ const COMPONENT_NAME$1g = 'vc-clipboard';
1511
1511
  const Clipboard = /* @__PURE__ */ vue.defineComponent({
1512
- name: COMPONENT_NAME$1d,
1513
- props: props$12,
1512
+ name: COMPONENT_NAME$1g,
1513
+ props: props$14,
1514
1514
  setup(props, {
1515
1515
  slots
1516
1516
  }) {
@@ -1524,31 +1524,247 @@ const Clipboard = /* @__PURE__ */ vue.defineComponent({
1524
1524
 
1525
1525
  const MClipboard = Clipboard;
1526
1526
 
1527
+ const props$13 = {
1528
+ tag: {
1529
+ type: String,
1530
+ default: "div"
1531
+ },
1532
+ accordion: {
1533
+ type: Boolean,
1534
+ default: false
1535
+ },
1536
+ modelValue: {
1537
+ type: [Array, String, Number]
1538
+ },
1539
+ alive: {
1540
+ type: Boolean,
1541
+ default: true
1542
+ },
1543
+ // TODO: 添加默认样式
1544
+ styleless: {
1545
+ type: Boolean,
1546
+ default: false
1547
+ }
1548
+ };
1549
+
1550
+ const COMPONENT_NAME$1f = "vc-collapse";
1551
+ const Collapse = vue.defineComponent({
1552
+ name: COMPONENT_NAME$1f,
1553
+ props: props$13,
1554
+ emits: ["update:moodelValue", "change"],
1555
+ setup(props, { slots, emit }) {
1556
+ const instance = vue.getCurrentInstance();
1557
+ const currentValue = vue.ref();
1558
+ const items = vue.ref([]);
1559
+ const sync = () => {
1560
+ const v = props.accordion ? currentValue.value[0] : currentValue.value;
1561
+ emit("update:moodelValue", v);
1562
+ emit("change", v);
1563
+ };
1564
+ const setActive = () => {
1565
+ const activeKey = currentValue.value;
1566
+ vue.nextTick(() => {
1567
+ items.value.forEach((child, index) => {
1568
+ const value = typeof child.props.value !== "undefined" ? child.props.value : index;
1569
+ child.exposed.toggle(activeKey.indexOf(value) > -1);
1570
+ });
1571
+ });
1572
+ };
1573
+ const toggle = (item) => {
1574
+ const activeKey = currentValue.value;
1575
+ const index = activeKey.indexOf(item.value);
1576
+ if (!item.visible) {
1577
+ if (index > -1) {
1578
+ activeKey.splice(index, 1);
1579
+ }
1580
+ } else if (index < 0) {
1581
+ activeKey.push(item.value);
1582
+ }
1583
+ currentValue.value = props.accordion ? activeKey.slice(-1) : activeKey;
1584
+ sync();
1585
+ };
1586
+ const add = (item, setValue) => {
1587
+ if (!item) return;
1588
+ vue.nextTick(() => {
1589
+ if (instance.vnode.el) {
1590
+ const index = Array.from(instance.vnode.el.children).filter((i) => /vcm?-collapse-item/.test(i.className)).indexOf(item.vnode.el);
1591
+ if (index != -1) {
1592
+ items.value.splice(index, 0, item);
1593
+ typeof item.props.value === "undefined" && setValue(index);
1594
+ return;
1595
+ }
1596
+ }
1597
+ items.value.push(item);
1598
+ typeof item.props.value === "undefined" && setValue(items.value.length - 1);
1599
+ });
1600
+ };
1601
+ const remove = (item, setValue) => {
1602
+ if (!item) return;
1603
+ items.value.splice(items.value.indexOf(item), 1);
1604
+ items.value.forEach((_, index) => setValue(index));
1605
+ };
1606
+ vue.provide("vc-collapse", {
1607
+ props,
1608
+ toggle,
1609
+ add,
1610
+ remove
1611
+ });
1612
+ vue.watch(
1613
+ () => props.modelValue,
1614
+ (v) => {
1615
+ if (v === currentValue.value) return;
1616
+ currentValue.value = props.accordion && typeof v !== "undefined" ? Array.isArray(v) ? v : [v] : Array.isArray(v) ? v : [];
1617
+ },
1618
+ { immediate: true }
1619
+ );
1620
+ vue.watch(
1621
+ () => currentValue.value,
1622
+ setActive,
1623
+ { deep: true }
1624
+ );
1625
+ vue.onMounted(setActive);
1626
+ return () => {
1627
+ return vue.h(
1628
+ props.tag,
1629
+ {
1630
+ class: [{ "vc-collapse": !props.styleless }]
1631
+ },
1632
+ slots.default?.()
1633
+ );
1634
+ };
1635
+ }
1636
+ });
1637
+
1638
+ const props$12 = {
1639
+ tag: {
1640
+ type: String,
1641
+ default: "div"
1642
+ },
1643
+ value: {
1644
+ type: [String, Number]
1645
+ }
1646
+ };
1647
+
1527
1648
  const props$11 = {
1528
1649
  tag: {
1529
1650
  type: String,
1530
1651
  default: "div"
1652
+ },
1653
+ modelValue: {
1654
+ type: Boolean,
1655
+ default: false
1656
+ },
1657
+ // 子节点每次toggle不销毁
1658
+ alive: {
1659
+ type: Boolean,
1660
+ default: true
1531
1661
  }
1532
1662
  };
1533
1663
 
1534
1664
  /** @jsxImportSource vue */
1535
1665
 
1536
- const COMPONENT_NAME$1c = 'vc-collapse';
1537
- const Collapse = /* @__PURE__ */ vue.defineComponent({
1538
- name: COMPONENT_NAME$1c,
1666
+ function _isSlot$2(s) {
1667
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
1668
+ }
1669
+ const COMPONENT_NAME$1e = 'vc-expand';
1670
+ const Expand = /* @__PURE__ */ vue.defineComponent({
1671
+ name: COMPONENT_NAME$1e,
1539
1672
  props: props$11,
1540
1673
  setup(props, {
1541
1674
  slots
1542
1675
  }) {
1676
+ const isActive = vue.ref(false);
1677
+ const Content = props.tag;
1678
+ vue.watch(() => props.modelValue, v => {
1679
+ isActive.value = v;
1680
+ }, {
1681
+ immediate: true
1682
+ });
1543
1683
  return () => {
1544
- return vue.createVNode("div", {
1545
- "class": "vc-collapse"
1546
- }, [slots?.default?.()]);
1684
+ let _slot;
1685
+ return vue.createVNode(TransitionCollapse, {
1686
+ "duration": {
1687
+ enter: 200,
1688
+ leave: 200
1689
+ }
1690
+ }, _isSlot$2(_slot = vue.withDirectives(vue.createVNode(Content, null, {
1691
+ default: () => [(props.alive || !props.alive && isActive.value) && slots.default?.()]
1692
+ }), [[vue.vShow, isActive.value]])) ? _slot : {
1693
+ default: () => [_slot]
1694
+ });
1695
+ };
1696
+ }
1697
+ });
1698
+
1699
+ /** @jsxImportSource vue */
1700
+
1701
+ const COMPONENT_NAME$1d = 'vc-collapse-item';
1702
+ const CollapseItem = /* @__PURE__ */ vue.defineComponent({
1703
+ name: COMPONENT_NAME$1d,
1704
+ props: props$12,
1705
+ setup(props, {
1706
+ slots,
1707
+ expose
1708
+ }) {
1709
+ const Content = props.tag;
1710
+ const instance = vue.getCurrentInstance();
1711
+ const isActive = vue.ref(false);
1712
+ const current = vue.ref();
1713
+ const collapse = vue.inject('vc-collapse');
1714
+ const handleToggle = () => {
1715
+ collapse.toggle({
1716
+ value: typeof props.value !== 'undefined' ? props.value : current.value,
1717
+ visible: !isActive.value
1718
+ });
1719
+ };
1720
+ const alive = vue.computed(() => {
1721
+ return collapse.props.alive;
1722
+ });
1723
+ const styleless = vue.computed(() => {
1724
+ return collapse.props.styleless;
1725
+ });
1726
+ const setValue = v => current.value = v;
1727
+ vue.onBeforeMount(() => {
1728
+ collapse.add?.(instance, setValue);
1729
+ });
1730
+ vue.onBeforeUnmount(() => {
1731
+ collapse.remove?.(instance, setValue);
1732
+ });
1733
+ expose({
1734
+ isActive,
1735
+ toggle: v => isActive.value = v
1736
+ });
1737
+ return () => {
1738
+ return vue.createVNode(Content, {
1739
+ "class": [{
1740
+ 'vc-collapse-item': !styleless.value
1741
+ }]
1742
+ }, {
1743
+ default: () => [vue.createVNode("div", {
1744
+ "class": [{
1745
+ 'vc-collapse-item__title': !styleless.value
1746
+ }],
1747
+ "onClick": handleToggle
1748
+ }, [slots.default?.(), slots.icon?.({
1749
+ visible: isActive.value
1750
+ })]), vue.createVNode(Expand, {
1751
+ "modelValue": isActive.value,
1752
+ "alive": alive.value,
1753
+ "onChange": v => isActive.value = v
1754
+ }, {
1755
+ default: () => [vue.createVNode("div", {
1756
+ "class": [{
1757
+ 'vc-collapse-item__content': !styleless.value
1758
+ }]
1759
+ }, [slots.content?.()])]
1760
+ })]
1761
+ });
1547
1762
  };
1548
1763
  }
1549
1764
  });
1550
1765
 
1551
1766
  const MCollapse = Collapse;
1767
+ const MCollapseItem = CollapseItem;
1552
1768
 
1553
1769
  const props$10 = {
1554
1770
  tag: {
@@ -1559,9 +1775,9 @@ const props$10 = {
1559
1775
 
1560
1776
  /** @jsxImportSource vue */
1561
1777
 
1562
- const COMPONENT_NAME$1b = 'vc-color-picker';
1778
+ const COMPONENT_NAME$1c = 'vc-color-picker';
1563
1779
  const ColorPicker = /* @__PURE__ */ vue.defineComponent({
1564
- name: COMPONENT_NAME$1b,
1780
+ name: COMPONENT_NAME$1c,
1565
1781
  props: props$10,
1566
1782
  setup(props, {
1567
1783
  slots
@@ -1585,9 +1801,9 @@ const props$$ = {
1585
1801
 
1586
1802
  /** @jsxImportSource vue */
1587
1803
 
1588
- const COMPONENT_NAME$1a = 'vc-countdown';
1804
+ const COMPONENT_NAME$1b = 'vc-countdown';
1589
1805
  const Countdown = /* @__PURE__ */ vue.defineComponent({
1590
- name: COMPONENT_NAME$1a,
1806
+ name: COMPONENT_NAME$1b,
1591
1807
  props: props$$,
1592
1808
  setup(props, {
1593
1809
  slots
@@ -1609,9 +1825,9 @@ const props$_ = {
1609
1825
  }
1610
1826
  };
1611
1827
 
1612
- const COMPONENT_NAME$19 = "vc-customer";
1828
+ const COMPONENT_NAME$1a = "vc-customer";
1613
1829
  const Customer = vue.defineComponent({
1614
- name: COMPONENT_NAME$19,
1830
+ name: COMPONENT_NAME$1a,
1615
1831
  props: props$_,
1616
1832
  setup(props, context) {
1617
1833
  return () => vue.h(() => {
@@ -1631,9 +1847,9 @@ const props$Z = {
1631
1847
 
1632
1848
  /** @jsxImportSource vue */
1633
1849
 
1634
- const COMPONENT_NAME$18 = 'vc-date-picker';
1850
+ const COMPONENT_NAME$19 = 'vc-date-picker';
1635
1851
  const DatePicker = /* @__PURE__ */ vue.defineComponent({
1636
- name: COMPONENT_NAME$18,
1852
+ name: COMPONENT_NAME$19,
1637
1853
  props: props$Z,
1638
1854
  setup(props, {
1639
1855
  slots
@@ -1657,9 +1873,9 @@ const props$Y = {
1657
1873
 
1658
1874
  /** @jsxImportSource vue */
1659
1875
 
1660
- const COMPONENT_NAME$17 = 'vc-divider';
1876
+ const COMPONENT_NAME$18 = 'vc-divider';
1661
1877
  const Divider = /* @__PURE__ */ vue.defineComponent({
1662
- name: COMPONENT_NAME$17,
1878
+ name: COMPONENT_NAME$18,
1663
1879
  props: props$Y,
1664
1880
  setup(props, {
1665
1881
  slots
@@ -1674,1085 +1890,1286 @@ const Divider = /* @__PURE__ */ vue.defineComponent({
1674
1890
 
1675
1891
  const MDivider = Divider;
1676
1892
 
1677
- const props$X = {
1678
- tag: {
1679
- type: String,
1680
- default: "div"
1681
- }
1682
- };
1683
-
1684
- /** @jsxImportSource vue */
1685
-
1686
- const COMPONENT_NAME$16 = 'vc-drawer';
1687
- const Drawer = /* @__PURE__ */ vue.defineComponent({
1688
- name: COMPONENT_NAME$16,
1689
- props: props$X,
1690
- setup(props, {
1691
- slots
1692
- }) {
1693
- return () => {
1694
- return vue.createVNode("div", {
1695
- "class": "vc-drawer"
1696
- }, [slots?.default?.()]);
1697
- };
1698
- }
1699
- });
1700
-
1701
- const MDrawer = Drawer;
1702
-
1703
- const props$W = {
1704
- tag: {
1705
- type: String,
1706
- default: "div"
1707
- }
1708
- };
1709
-
1710
- /** @jsxImportSource vue */
1711
-
1712
- const COMPONENT_NAME$15 = 'vc-dropdown';
1713
- const Dropdown = /* @__PURE__ */ vue.defineComponent({
1714
- name: COMPONENT_NAME$15,
1715
- props: props$W,
1716
- setup(props, {
1717
- slots
1718
- }) {
1719
- return () => {
1720
- return vue.createVNode("div", {
1721
- "class": "vc-dropdown"
1722
- }, [slots?.default?.()]);
1723
- };
1724
- }
1725
- });
1726
-
1727
- const MDropdown = Dropdown;
1728
-
1729
- const props$V = {
1730
- tag: {
1731
- type: String,
1732
- default: "div"
1733
- }
1893
+ const defaults = {
1894
+ tag: "div",
1895
+ el: "body",
1896
+ alive: false,
1897
+ multiple: false,
1898
+ aliveRegExp: { className: /(vc-hack-alive|vc-hack-cp)/ },
1899
+ aliveVisibleKey: "isVisible",
1900
+ aliveUpdateKey: "update",
1901
+ leaveDelay: 300,
1902
+ autoDestroy: true,
1903
+ components: {},
1904
+ uses: {},
1905
+ fragment: false,
1906
+ insertion: "last"
1734
1907
  };
1735
1908
 
1736
- /** @jsxImportSource vue */
1737
-
1738
- const COMPONENT_NAME$14 = 'vc-editor';
1739
- const Editor = /* @__PURE__ */ vue.defineComponent({
1740
- name: COMPONENT_NAME$14,
1741
- props: props$V,
1742
- setup(props, {
1743
- slots
1744
- }) {
1745
- return () => {
1746
- return vue.createVNode("div", {
1747
- "class": "vc-editor"
1748
- }, [slots?.default?.()]);
1909
+ class PortalLeaf {
1910
+ app;
1911
+ /**
1912
+ * 目标的实例,挂载到app上
1913
+ */
1914
+ wrapper;
1915
+ propsData;
1916
+ /**
1917
+ * 销毁的函数,挂载到app上,避免冲突
1918
+ */
1919
+ destroy;
1920
+ /**
1921
+ * 自动销毁的标记,挂载到app上,避免冲突
1922
+ */
1923
+ autoDestroy;
1924
+ target;
1925
+ constructor(target) {
1926
+ this.target = target;
1927
+ this.autoDestroy = false;
1928
+ this.destroy = /* istanbul ignore next */
1929
+ () => {
1930
+ throw new VcError("portal", "未注册的destroy方法");
1749
1931
  };
1750
1932
  }
1751
- });
1752
-
1753
- const MEditor = Editor;
1754
-
1755
- const props$U = {
1756
- tag: {
1757
- type: String,
1758
- default: "div"
1933
+ then(resolve, reject) {
1934
+ return this.target.then(resolve, reject);
1759
1935
  }
1760
- };
1761
-
1762
- /** @jsxImportSource vue */
1763
-
1764
- const COMPONENT_NAME$13 = 'vc-expand';
1765
- const Expand = /* @__PURE__ */ vue.defineComponent({
1766
- name: COMPONENT_NAME$13,
1767
- props: props$U,
1768
- setup(props, {
1769
- slots
1770
- }) {
1771
- return () => {
1772
- return vue.createVNode("div", {
1773
- "class": "vc-expand"
1774
- }, [slots?.default?.()]);
1775
- };
1936
+ catch(callback) {
1937
+ return this.target.catch(callback);
1776
1938
  }
1777
- });
1778
-
1779
- const MExpand = Expand;
1780
-
1781
- const props$T = {
1782
- tag: {
1783
- type: String,
1784
- default: "form"
1785
- },
1786
- model: {
1787
- type: Object
1788
- },
1789
- rules: {
1790
- type: Object
1791
- },
1792
- labelWidth: {
1793
- type: Number
1794
- },
1795
- showMessage: {
1796
- type: Boolean,
1797
- default: true
1798
- },
1799
- inline: {
1800
- type: Boolean,
1801
- default: false
1802
- },
1803
- labelPosition: {
1804
- type: String,
1805
- default: "right"
1806
- },
1807
- autocomplete: {
1808
- type: String,
1809
- default: "off"
1810
- },
1811
- styleless: {
1812
- type: Boolean,
1813
- default: false
1939
+ finally(callback) {
1940
+ return this.target.finally(callback);
1814
1941
  }
1815
- };
1942
+ }
1816
1943
 
1817
- const useForm = (expose, options = {}) => {
1818
- const instance = vue.getCurrentInstance();
1819
- const props = instance.props;
1820
- const fields = [];
1821
- vue.provide("form", {
1822
- props,
1823
- add: (field) => {
1824
- field && fields.push(field);
1825
- },
1826
- remove: (field) => {
1827
- field && fields.splice(fields.indexOf(field), 1);
1828
- }
1829
- });
1830
- const filterFields = (fields$) => {
1831
- return !fields$ ? fields : fields.filter((item) => fields$.includes(item.props.prop));
1832
- };
1833
- const getField = (prop) => {
1834
- const field = fields.find((item) => item.props.prop === prop);
1835
- if (!field) throw new VcError("form", "请选择有用的prop值");
1836
- return field;
1837
- };
1838
- const showToast = (msg) => {
1839
- props.showMessage && options.throwToast?.(msg);
1840
- };
1841
- const sortErrors = async (errors) => {
1842
- const positions = await Promise.all(fields.map((item) => item.exposed.getPosition()));
1944
+ const COMPONENT_NAME$17 = "vc-portal";
1945
+ class Portal {
1946
+ /**
1947
+ * 清理Portals类型组件
1948
+ * @param name 清理的组件名, boolean表示全部leafs是否强制清理
1949
+ */
1950
+ static clear(name) {
1843
1951
  try {
1844
- return [...errors].toSorted((a, b) => {
1845
- const aIndex = fields.findIndex((i) => i.props.prop === a.prop);
1846
- const bIndex = fields.findIndex((i) => i.props.prop === b.prop);
1847
- const aPosition = positions[aIndex];
1848
- const bPosition = positions[bIndex];
1849
- if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
1850
- return aPosition.left - bPosition.left;
1851
- });
1852
- } catch (e) {
1853
- return errors;
1854
- }
1855
- };
1856
- const scrollIntoView = (prop) => {
1857
- const field = getField(prop);
1858
- field.vnode?.el?.scrollIntoView?.({
1859
- behavior: "smooth",
1860
- block: "center"
1861
- });
1862
- };
1863
- const reset = (options$ = {}) => {
1864
- const { fields: fields$, original = {} } = options$;
1865
- filterFields(fields$).forEach((field) => {
1866
- let v;
1867
- try {
1868
- v = Utils.getPropByPath(original, field.props.prop).v;
1869
- } catch (e) {
1952
+ let force = false;
1953
+ let target = /* @__PURE__ */ new Map();
1954
+ if (name && typeof name !== "boolean") {
1955
+ let names = [];
1956
+ if (typeof name === "string") {
1957
+ names = [name];
1958
+ } else if (name instanceof Array && name.length > 0) {
1959
+ names = name;
1960
+ }
1961
+ names.forEach((i) => target.set(i, ""));
1962
+ force = true;
1963
+ } else {
1964
+ force = !!name;
1965
+ target = Portal.leafs;
1966
+ }
1967
+ for (const key of target.keys()) {
1968
+ const leaf = Portal.leafs.get(key);
1969
+ if (leaf && (force === true || leaf.autoDestroy === true)) {
1970
+ leaf.destroy();
1971
+ }
1870
1972
  }
1871
- field.exposed.reset(v);
1872
- });
1873
- };
1874
- const validate = async (options$ = {}) => {
1875
- const { scroll = true, fields: fields$ } = options$;
1876
- if (!fields.length) {
1877
- return;
1878
- }
1879
- const results = await Promise.allSettled(
1880
- filterFields(fields$).map((item) => item.exposed.validate(""))
1881
- );
1882
- const originErrors = results.filter((i) => i.status === "rejected").map((i) => i.reason);
1883
- if (!originErrors.length) return;
1884
- const errors = await sortErrors(originErrors);
1885
- showToast(errors[0].msg || errors[0].message);
1886
- scroll && scrollIntoView(errors[0].prop);
1887
- throw errors;
1888
- };
1889
- const validateField = async (prop, options$ = {}) => {
1890
- try {
1891
- await validate({
1892
- ...options$,
1893
- fields: [prop]
1894
- });
1895
1973
  } catch (e) {
1896
- throw e[0];
1974
+ /* istanbul ignore next -- @preserve */
1975
+ throw new VcError("instance", e);
1897
1976
  }
1898
- };
1899
- expose({
1900
- reset,
1901
- validate,
1902
- // 单个操作
1903
- getField,
1904
- validateField
1905
- });
1906
- };
1907
-
1908
- const COMPONENT_NAME$12 = "vc-form";
1909
- const Form = vue.defineComponent({
1910
- name: COMPONENT_NAME$12,
1911
- props: props$T,
1912
- setup(props, { slots, expose }) {
1913
- useForm(expose);
1914
- return () => {
1915
- return vue.h(
1916
- props.tag,
1917
- {
1918
- class: "vc-form",
1919
- autocomplete: props.autocomplete
1920
- },
1921
- slots
1922
- );
1923
- };
1924
1977
  }
1925
- });
1926
-
1927
- const props$S = {
1928
- label: {
1929
- type: String,
1930
- default: ""
1931
- },
1932
- labelWidth: {
1933
- type: Number
1934
- },
1935
- prop: {
1936
- type: String
1937
- },
1938
- required: {
1939
- type: [Boolean, String],
1940
- default: false
1941
- },
1942
- error: {
1943
- type: String
1944
- },
1945
- rules: {
1946
- type: [Array, Object]
1947
- },
1948
- resetByRulesChanged: {
1949
- type: Boolean,
1950
- default: false
1951
- },
1952
- showMessage: {
1953
- type: Boolean,
1954
- default: true
1955
- },
1956
- labelFor: {
1957
- type: String
1958
- },
1959
- styleless: {
1960
- type: Boolean,
1961
- default: false
1962
- },
1963
- labelPosition: {
1964
- type: String,
1965
- default: "right"
1966
- },
1967
- contentStyle: String
1968
- };
1969
-
1970
- const filterEmpty = (val) => {
1971
- if (val instanceof Array) {
1972
- val = val.filter((i) => i !== "");
1978
+ /**
1979
+ * 清理全部Portals
1980
+ */
1981
+ static clearAll() {
1982
+ try {
1983
+ Portal.leafs.forEach((leaf) => leaf.destroy());
1984
+ } catch (e) {
1985
+ /* istanbul ignore next -- @preserve */
1986
+ throw new VcError("instance", e);
1987
+ }
1973
1988
  }
1974
- return val;
1975
- };
1976
- const toRules = (rules) => {
1977
- return rules instanceof Array ? rules : rules ? [rules] : [];
1978
- };
1979
- const useFormItem = (expose) => {
1980
- const form = vue.inject("form");
1981
- const instance = vue.getCurrentInstance();
1982
- const props = instance.props;
1983
- const { slots } = instance;
1984
- if (!form?.props) {
1985
- throw new VcError("form-item", "form-item需要在form内使用");
1989
+ static leafs = /* @__PURE__ */ new Map();
1990
+ wrapper;
1991
+ globalOptions;
1992
+ constructor(wrapper, options) {
1993
+ this.wrapper = wrapper;
1994
+ this.globalOptions = {
1995
+ ...options,
1996
+ name: options?.name || wrapper.name || Utils__namespace.getUid(COMPONENT_NAME$17)
1997
+ };
1986
1998
  }
1987
- const formItem = vue.inject("form-item", {});
1988
- const validateState = vue.ref("");
1989
- const validateMessage = vue.ref("");
1990
- let validateDisabled = false;
1991
- let initialValue;
1992
- const currentRules = vue.computed(() => {
1993
- const formRules = form.props.rules;
1994
- const formItemBindRules = toRules(props.rules);
1995
- let formItemRules = formItemBindRules;
1996
- if (!formItemRules.length && formRules && props.prop) {
1997
- try {
1998
- const key = props.prop.replace(/\.[0-9]+\./g, ".");
1999
- const { v } = Utils.getPropByPath(formRules, key);
2000
- formItemRules = toRules(v);
2001
- } catch {
2002
- const rules = formRules[props.prop];
2003
- formItemRules = toRules(rules);
2004
- }
2005
- }
2006
- return formItemRules;
2007
- });
2008
- const isRequired = vue.computed(() => {
2009
- if (!currentRules.value.length) {
2010
- return !!props.required;
1999
+ popup(propsData, options) {
2000
+ if (!options) {
2001
+ options = propsData || {};
2002
+ } else {
2003
+ options.propsData = propsData;
2011
2004
  }
2012
- let required = false;
2013
- for (let i = 0; i < currentRules.value.length; i++) {
2014
- const rule = currentRules.value[i];
2015
- required = !!rule.required;
2016
- if (required) break;
2005
+ const $options = { ...this.getDefaultOptions(), ...options };
2006
+ const { onFulfilled, onRejected, ...rest } = $options;
2007
+ let onFulfilled$ = (
2008
+ /* istanbul ignore next -- @preserve */
2009
+ () => {
2010
+ }
2011
+ );
2012
+ let onRejected$ = (
2013
+ /* istanbul ignore next -- @preserve */
2014
+ () => {
2015
+ }
2016
+ );
2017
+ const target = new Promise((resolve, reject) => {
2018
+ onFulfilled$ = (v) => {
2019
+ onFulfilled?.(v);
2020
+ resolve(v);
2021
+ };
2022
+ onRejected$ = (v) => {
2023
+ onRejected?.(v);
2024
+ reject(v);
2025
+ };
2026
+ });
2027
+ return this.render(rest, target, onFulfilled$, onRejected$);
2028
+ }
2029
+ /**
2030
+ * 销毁当前Portal下的节点
2031
+ * @param target [description]
2032
+ */
2033
+ destroy = (target) => {
2034
+ const { multiple, name } = this.getDefaultOptions();
2035
+ target = target || name;
2036
+ const instance = typeof target === "object" ? target : Portal.leafs.get(target);
2037
+ if (instance) {
2038
+ instance.destroy();
2039
+ } else if (multiple) {
2040
+ Portal.leafs.forEach((item, key) => {
2041
+ if (key.includes(name)) {
2042
+ item.destroy();
2043
+ }
2044
+ });
2017
2045
  }
2018
- return required;
2019
- });
2020
- const labelPosition = vue.computed(() => {
2021
- return props.labelPosition || form.props.labelPosition;
2022
- });
2023
- const classes = vue.computed(() => {
2046
+ };
2047
+ getDefaultOptions() {
2024
2048
  return {
2025
- "is-require": isRequired.value,
2026
- "is-error": validateState.value === "error",
2027
- "is-validating": validateState.value === "validating",
2028
- "is-inline": form.props.inline,
2029
- "is-nest": isNest.value,
2030
- [`is-${labelPosition.value}`]: true
2049
+ ...defaults,
2050
+ ...VcInstance.options.Portal,
2051
+ ...this.globalOptions
2031
2052
  };
2032
- });
2033
- const isNest = vue.computed(() => {
2034
- return !!formItem.change;
2035
- });
2036
- const isNestLast = vue.ref(false);
2037
- const hasLabel = vue.computed(() => {
2038
- return !!props.label || slots.label;
2039
- });
2040
- const labelStyle = vue.computed(() => {
2041
- const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNest.value ? 0 : form.props.labelWidth;
2042
- return {
2043
- width: labelPosition.value !== "top" && labelWidth && labelWidth > 0 ? `${labelWidth}px` : "auto",
2044
- textAlign: labelPosition.value === "top" ? "left" : labelPosition.value
2053
+ }
2054
+ createCallback(getLeaf, delay, callback) {
2055
+ return (...args) => {
2056
+ const done = () => {
2057
+ const leaf = getLeaf();
2058
+ /* istanbul ignore next -- @preserve */
2059
+ if (!leaf) {
2060
+ throw new VcError("portal", "实例不存在或已卸载");
2061
+ }
2062
+ leaf.destroy();
2063
+ };
2064
+ delay ? setTimeout(done, delay) : done();
2065
+ callback?.(...args);
2045
2066
  };
2046
- });
2047
- const contentStyle = vue.computed(() => {
2048
- const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : form.props.labelWidth;
2049
- return [
2050
- {
2051
- marginLeft: !hasLabel.value && isNest.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
2052
- marginBottom: isNest.value && !isNestLast.value ? `20px` : 0
2053
- },
2054
- props.contentStyle
2055
- ];
2056
- });
2057
- const isStyleless = vue.computed(() => {
2058
- return props.styleless || form.props.styleless;
2059
- });
2060
- const fieldValue = vue.computed(() => {
2061
- const model = form.props.model;
2062
- if (!model || !props.prop) {
2063
- return;
2064
- }
2065
- let path = props.prop;
2066
- if (path.includes(":")) {
2067
- path = path.replace(/:/, ".");
2068
- }
2069
- return Utils.getPropByPath(model, path).v;
2070
- });
2071
- const showError = vue.computed(() => {
2072
- return validateState.value === "error" && props.showMessage && form.props.showMessage;
2073
- });
2074
- vue.watch(
2075
- () => props.error,
2076
- (v) => {
2077
- validateMessage.value = v || "";
2078
- validateState.value = v === "" ? "" : "error";
2079
- }
2080
- );
2081
- const reset = (v) => {
2082
- validateState.value = "";
2083
- validateMessage.value = "";
2084
- const model = form.props.model;
2085
- if (!props.prop) return;
2086
- const { o, k } = Utils.getPropByPath(model, props.prop);
2087
- if (!k) return;
2088
- validateDisabled = true;
2089
- o[k] = v !== null && v !== void 0 ? v : Array.isArray(fieldValue.value) ? [].concat(initialValue) : initialValue;
2090
- };
2091
- const validate = async (trigger) => {
2092
- if (!props.prop) return;
2093
- let rules = currentRules.value.filter((rule) => !rule.trigger || rule.trigger.includes(trigger));
2094
- if (!rules.length) {
2095
- if (!props.required) {
2096
- return;
2097
- } else {
2098
- rules = [{
2099
- required: true,
2100
- message: typeof props.required === "string" ? props.required : void 0
2101
- }];
2067
+ }
2068
+ render(options, target, onFulfilled, onRejected) {
2069
+ const {
2070
+ el,
2071
+ tag,
2072
+ alive,
2073
+ aliveRegExp,
2074
+ aliveVisibleKey,
2075
+ aliveUpdateKey,
2076
+ name: name$,
2077
+ leaveDelay,
2078
+ autoDestroy,
2079
+ multiple,
2080
+ fragment,
2081
+ onDestroyed,
2082
+ onBeforeCreate,
2083
+ insertion,
2084
+ // 全局注册
2085
+ globalProperties,
2086
+ install,
2087
+ components,
2088
+ uses,
2089
+ slots,
2090
+ parent,
2091
+ propsData,
2092
+ ...rest
2093
+ } = options;
2094
+ let useAllNodes = fragment;
2095
+ const name = multiple ? `${name$}__${Utils__namespace.getUid(COMPONENT_NAME$17)}` : name$;
2096
+ const container = document.createElement(tag);
2097
+ const root = typeof el === "object" ? el : document.querySelector(el || "body");
2098
+ !alive && Portal.leafs.get(name)?.destroy();
2099
+ const propsData$ = propsData || rest;
2100
+ let leaf = new PortalLeaf(target);
2101
+ const isDestroyed = () => {
2102
+ const leaf$ = Portal.leafs.get(name);
2103
+ return !leaf$ || leaf$ !== leaf;
2104
+ };
2105
+ const $onDestroyed = (...args) => {
2106
+ if (isDestroyed()) return;
2107
+ onDestroyed?.(...args);
2108
+ leaf.app?.unmount();
2109
+ /* istanbul ignore else -- @preserve */
2110
+ if (useAllNodes) {
2111
+ root?.contains(container) && root.removeChild(container);
2112
+ } else if (container && container._children) {
2113
+ container._children.forEach((i) => {
2114
+ root?.contains(i) && root.removeChild(i);
2115
+ });
2102
2116
  }
2103
- }
2104
- validateState.value = "validating";
2105
- const descriptor = {};
2106
- descriptor[props.prop] = rules;
2107
- const validator = new helperValidator.Validator(descriptor);
2108
- const model = {};
2109
- model[props.prop] = filterEmpty(fieldValue.value);
2110
- try {
2111
- await validator.validate(model, { first: false });
2112
- validateState.value = "success";
2113
- validateMessage.value = "";
2114
- } catch (errors) {
2115
- validateState.value = "error";
2116
- validateMessage.value = errors[0].message;
2117
- throw {
2118
- prop: props.prop,
2119
- message: validateMessage.value
2120
- };
2121
- }
2122
- validateDisabled = false;
2123
- };
2124
- const handleFieldBlur = () => {
2125
- if (!props.prop) {
2126
- formItem.blur?.();
2127
- return;
2128
- }
2129
- validate("blur");
2130
- };
2131
- const handleFieldChange = () => {
2132
- if (!props.prop) {
2133
- formItem.change?.();
2134
- return;
2135
- }
2136
- if (validateDisabled) {
2137
- validateDisabled = false;
2138
- return;
2139
- }
2140
- validate("change");
2141
- };
2142
- const getPosition = async () => {
2143
- let el = instance.vnode.el;
2144
- try {
2145
- while (el && !el.getBoundingClientRect) {
2146
- el = el.nextSibling;
2117
+ Portal.leafs.delete(name);
2118
+ };
2119
+ const $onRejected = this.createCallback(() => leaf, leaveDelay, onRejected);
2120
+ const $onFulfilled = this.createCallback(() => leaf, leaveDelay, onFulfilled);
2121
+ if (alive && Portal.leafs.has(name)) {
2122
+ leaf = Portal.leafs.get(name);
2123
+ leaf.target = target;
2124
+ leaf.propsData.value = propsData$;
2125
+ leaf.wrapper?.[aliveUpdateKey]?.(options);
2126
+ } else {
2127
+ const wrapper = this.wrapper;
2128
+ const app = vue.createApp({
2129
+ name: COMPONENT_NAME$17,
2130
+ parent,
2131
+ setup() {
2132
+ if (alive) {
2133
+ const handleExtra = (e) => {
2134
+ try {
2135
+ const path = e.path || $__namespace.composedPath(e);
2136
+ /* istanbul ignore else -- @preserve */
2137
+ if (container && e.target && !container.contains(e.target) && !path?.some((item) => vcShared.Utils.eleInRegExp(item, aliveRegExp))) {
2138
+ /* istanbul ignore else -- @preserve */
2139
+ if (leaf.wrapper && leaf.wrapper?.[aliveVisibleKey]) {
2140
+ leaf.wrapper[aliveVisibleKey] = false;
2141
+ }
2142
+ leaveDelay ? setTimeout($onDestroyed, leaveDelay) : $onDestroyed();
2143
+ }
2144
+ } catch (error) {
2145
+ /* istanbul ignore next -- @preserve */
2146
+ throw new VcError("portal", error);
2147
+ }
2148
+ };
2149
+ vue.onMounted(() => {
2150
+ document.addEventListener("click", handleExtra, true);
2151
+ });
2152
+ vue.onBeforeUnmount(() => {
2153
+ document.removeEventListener("click", handleExtra, true);
2154
+ });
2155
+ }
2156
+ const propsData1 = vue.ref(propsData$);
2157
+ const propsData2 = vue.ref();
2158
+ leaf.propsData = propsData1;
2159
+ const allowMounted = vue.ref(typeof onBeforeCreate !== "function");
2160
+ if (!allowMounted.value) {
2161
+ const result = onBeforeCreate(propsData$);
2162
+ if (result && result.then) {
2163
+ result.then((response) => {
2164
+ if (isDestroyed()) return;
2165
+ allowMounted.value = true;
2166
+ propsData2.value = response;
2167
+ }).catch((error) => {
2168
+ $onDestroyed(error);
2169
+ });
2170
+ } else {
2171
+ allowMounted.value = true;
2172
+ propsData2.value = result;
2173
+ }
2174
+ }
2175
+ return () => allowMounted.value && vue.h(
2176
+ wrapper,
2177
+ {
2178
+ ...propsData1.value,
2179
+ ...propsData2.value,
2180
+ ref: (vm) => leaf.wrapper = vm,
2181
+ onPortalFulfilled: (...args) => $onFulfilled(...args),
2182
+ onPortalRejected: (...args) => $onRejected(...args),
2183
+ onPortalDestroyed: (...args) => $onDestroyed(...args)
2184
+ },
2185
+ slots || void 0
2186
+ );
2187
+ }
2188
+ });
2189
+ leaf.app = app;
2190
+ if (globalProperties) {
2191
+ app.config.globalProperties = globalProperties;
2147
2192
  }
2148
- ;
2149
- const rect = el.getBoundingClientRect();
2150
- return {
2151
- top: rect.top,
2152
- left: rect.left
2153
- };
2154
- } catch (e) {
2155
- throw new VcError("form-item", "form-item位置计算错误");
2156
- }
2157
- };
2158
- const fields = vue.reactive([]);
2159
- vue.provide("form-item", {
2160
- fields,
2161
- blur: handleFieldBlur,
2162
- change: handleFieldChange,
2163
- message: validateMessage,
2164
- add: (field) => {
2165
- field && fields.push(field);
2166
- },
2167
- remove: (field) => {
2168
- field && fields.splice(fields.indexOf(field), 1);
2169
- }
2170
- });
2171
- vue.onMounted(() => {
2172
- if (props.prop) {
2173
- form.add?.(instance);
2174
- initialValue = lodashEs.cloneDeep(fieldValue.value);
2175
- }
2176
- formItem.add?.(instance);
2177
- });
2178
- vue.onBeforeUnmount(() => {
2179
- form.remove?.(instance);
2180
- formItem.remove?.(instance);
2181
- });
2182
- vue.watch(
2183
- () => props.rules,
2184
- () => {
2185
- props.resetByRulesChanged && reset();
2193
+ for (const key in components) {
2194
+ app.component(key, components[key]);
2195
+ }
2196
+ for (const key in uses) {
2197
+ app.use(uses[key]);
2198
+ }
2199
+ install?.(app);
2200
+ app.mount(container);
2186
2201
  }
2187
- );
2188
- vue.watch(
2189
- () => formItem.fields?.length,
2190
- async (v) => {
2191
- if (!isNest.value || !v) return isNestLast.value = false;
2192
- const fields$ = [...vue.toRaw(formItem.fields)];
2193
- const positions = await Promise.all(fields$.map((item) => item.exposed.getPosition()));
2194
- const sortFields = fields$.toSorted((a, b) => {
2195
- const aIndex = fields$.findIndex((i) => i === a);
2196
- const bIndex = fields$.findIndex((i) => i === b);
2197
- const aPosition = positions[aIndex];
2198
- const bPosition = positions[bIndex];
2199
- if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
2200
- return aPosition.left - bPosition.left;
2202
+ leaf.destroy = $onDestroyed;
2203
+ leaf.autoDestroy = !!autoDestroy;
2204
+ Portal.leafs.set(name, leaf);
2205
+ const append = (root$, child$) => {
2206
+ if (!root$ || !child$) return;
2207
+ if (insertion === "first") {
2208
+ const firstEl = root$.firstElementChild;
2209
+ if (firstEl) {
2210
+ root$.insertBefore(child$, firstEl);
2211
+ return;
2212
+ }
2213
+ }
2214
+ root$.appendChild(child$);
2215
+ };
2216
+ if (fragment || typeof container._children === "undefined" && !Array.from(container.children).length) {
2217
+ useAllNodes = true;
2218
+ container.parentElement === null && append(root, container);
2219
+ } else if (!container._children) {
2220
+ container._children = [];
2221
+ let childs = Array.from(container.children);
2222
+ if (insertion === "first") {
2223
+ childs = childs.reverse();
2224
+ }
2225
+ childs.forEach((i) => {
2226
+ append(root, i);
2227
+ container._children?.push?.(i);
2201
2228
  });
2202
- isNestLast.value = sortFields[sortFields.length - 1] === instance;
2203
2229
  }
2204
- );
2205
- expose({
2206
- validate,
2207
- reset,
2208
- getPosition
2230
+ return leaf;
2231
+ }
2232
+ }
2233
+
2234
+ const props$X = {
2235
+ tag: {
2236
+ type: String,
2237
+ default: "div"
2238
+ }
2239
+ };
2240
+
2241
+ const COMPONENT_NAME$16 = 'vc-portal-view';
2242
+
2243
+ /**
2244
+ * 写法不同,但与vue@2.x 保持一致
2245
+ */
2246
+ const PortalView = /* @__PURE__ */ vue.defineComponent({
2247
+ name: COMPONENT_NAME$16,
2248
+ props: props$X,
2249
+ setup(props, {
2250
+ slots
2251
+ }) {
2252
+ return () => {
2253
+ /**
2254
+ * 考虑占位的情况下需要渲染default
2255
+ */
2256
+ return vue.h(vue.Fragment, [vue.h(props.tag, {
2257
+ class: 'vc-portal-view'
2258
+ }, slots?.default?.()), vue.h(vue.Teleport, {
2259
+ to: 'body'
2260
+ }, slots?.content?.())]);
2261
+ };
2262
+ }
2263
+ });
2264
+
2265
+ const props$W = {
2266
+ title: String,
2267
+ content: {
2268
+ type: [String, Function],
2269
+ default: ""
2270
+ },
2271
+ modelValue: {
2272
+ type: Boolean,
2273
+ default: false
2274
+ },
2275
+ width: {
2276
+ type: Number,
2277
+ default: 300
2278
+ },
2279
+ height: {
2280
+ type: Number,
2281
+ default: 300
2282
+ },
2283
+ mask: {
2284
+ type: Boolean,
2285
+ default: true
2286
+ },
2287
+ maskClosable: {
2288
+ type: Boolean,
2289
+ default: true
2290
+ },
2291
+ scrollable: {
2292
+ type: Boolean,
2293
+ default: false
2294
+ },
2295
+ placement: {
2296
+ type: String,
2297
+ default: "right"
2298
+ // top/right/left/bottom
2299
+ },
2300
+ maskStyle: [Object, String],
2301
+ wrapperClass: [Object, String],
2302
+ wrapperStyle: [Object, String],
2303
+ closeWithCancel: {
2304
+ type: Boolean,
2305
+ default: true
2306
+ // 如果关闭, cancel只能是取消的按钮
2307
+ },
2308
+ okText: {
2309
+ type: [String, Boolean],
2310
+ default: "确定"
2311
+ },
2312
+ cancelText: {
2313
+ type: [String, Boolean],
2314
+ default: "取消"
2315
+ },
2316
+ footer: {
2317
+ type: Boolean,
2318
+ default: true
2319
+ },
2320
+ /**
2321
+ * 兼容portal设计, 实现Promise方式
2322
+ */
2323
+ onOk: {
2324
+ type: Function
2325
+ },
2326
+ onCancel: {
2327
+ type: Function
2328
+ }
2329
+ };
2330
+
2331
+ /** @jsxImportSource vue */
2332
+
2333
+ function _isSlot$1(s) {
2334
+ return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
2335
+ }
2336
+ const COMPONENT_NAME$15 = 'vc-drawer';
2337
+ const DrawerView = /* @__PURE__ */ vue.defineComponent({
2338
+ name: COMPONENT_NAME$15,
2339
+ props: props$W,
2340
+ emits: ['close', 'update:modelValue', 'visible-change'],
2341
+ setup(props, {
2342
+ emit,
2343
+ slots,
2344
+ expose
2345
+ }) {
2346
+ const instance = vue.getCurrentInstance();
2347
+ const isActive = vue.ref(false);
2348
+ const classes = vue.computed(() => {
2349
+ return {
2350
+ [`is-${props.placement}`]: true
2351
+ };
2352
+ });
2353
+ const style = vue.computed(() => {
2354
+ return props.placement === 'top' || props.placement === 'bottom' ? {
2355
+ height: `${props.height}px`
2356
+ } : {
2357
+ width: `${props.width}px`
2358
+ };
2359
+ });
2360
+ vue.watch(() => props.modelValue, v => {
2361
+ isActive.value = v;
2362
+ }, {
2363
+ immediate: true
2364
+ });
2365
+ const handleBefore = (e, hook) => {
2366
+ if (!isActive.value) return;
2367
+ const fn = hook && hook(e);
2368
+ if (fn && fn.then) {
2369
+ return fn.then(res => {
2370
+ isActive.value = false;
2371
+ return res;
2372
+ });
2373
+ } else if (!fn || fn === true) {
2374
+ isActive.value = false;
2375
+ }
2376
+ };
2377
+
2378
+ // 关闭事件
2379
+ const handleClose = (e, closable) => {
2380
+ if (closable || props.maskClosable && e.target.classList.contains('vc-drawer__wrapper')) {
2381
+ // 用户主要取消与关闭事件关联
2382
+ if (props.closeWithCancel) {
2383
+ handleBefore(e, handleCancel);
2384
+ } else {
2385
+ isActive.value = false;
2386
+ }
2387
+ }
2388
+ };
2389
+
2390
+ /**
2391
+ * 动画执行后关闭, 关闭事件都会被执行
2392
+ * visible-change 由移除之后触发
2393
+ * 同时close兼容portal设计
2394
+ */
2395
+ const handleRemove = () => {
2396
+ !instance.isUnmounted && (emit('close'), emit('update:modelValue', false), emit('visible-change', false));
2397
+ };
2398
+
2399
+ // 用户点击确定的回调 兼容portal设计
2400
+ const handleOk = (...rest) => {
2401
+ const ok = instance.vnode.props?.onOk || props.onOk || (() => {});
2402
+ return ok(...rest);
2403
+ };
2404
+
2405
+ // 用户点击取消按钮时为取消 兼容portal设计
2406
+ const handleCancel = (...rest) => {
2407
+ const cancel = instance.vnode.props?.onCancel || props.onCancel || (() => {});
2408
+ return cancel(...rest);
2409
+ };
2410
+ vcHooks.useScrollbar(isActive);
2411
+ expose({
2412
+ isActive,
2413
+ // for portal
2414
+ toggle(v) {
2415
+ v = typeof v === 'boolean' ? v : !isActive.value;
2416
+ isActive.value = v;
2417
+ }
2418
+ });
2419
+ return () => {
2420
+ let _slot, _slot2;
2421
+ return vue.createVNode("div", {
2422
+ "class": [classes.value, 'vc-drawer']
2423
+ }, [vue.createVNode(TransitionFade, {
2424
+ "delay": 50
2425
+ }, _isSlot$1(_slot = vue.withDirectives(vue.createVNode("div", {
2426
+ "style": props.maskStyle,
2427
+ "class": "vc-drawer__mask",
2428
+ "onClick": e => handleClose(e, props.maskClosable)
2429
+ }, null), [[vue.vShow, props.mask && isActive.value]])) ? _slot : {
2430
+ default: () => [_slot]
2431
+ }), vue.createVNode(TransitionSlide, {
2432
+ "mode": props.placement,
2433
+ "onAfterLeave": handleRemove
2434
+ }, _isSlot$1(_slot2 = vue.withDirectives(vue.createVNode("div", {
2435
+ "class": [props.wrapperClass, 'vc-drawer__wrapper'],
2436
+ "style": [style.value, props.wrapperStyle]
2437
+ }, [vue.createVNode("div", {
2438
+ "class": "vc-drawer__container"
2439
+ }, [vue.createVNode("div", {
2440
+ "class": "vc-drawer__header"
2441
+ }, [slots.header ? slots.header() : typeof props.title === 'string' ? vue.createVNode("div", {
2442
+ "class": "vc-drawer__title",
2443
+ "innerHTML": props.title
2444
+ }, null) : typeof props.title === 'function' && vue.createVNode(Customer, {
2445
+ "render": props.title
2446
+ }, null), vue.createVNode("a", {
2447
+ "class": "vc-drawer__close",
2448
+ "onClick": e => handleClose(e, true)
2449
+ }, [vue.createVNode(Icon, {
2450
+ "type": "close"
2451
+ }, null)])]), vue.createVNode("div", {
2452
+ "class": ['vc-drawer__content']
2453
+ }, [typeof props.content === 'string' ? vue.createVNode("div", {
2454
+ "innerHTML": props.content
2455
+ }, null) : typeof props.content === 'function' ? vue.createVNode(Customer, {
2456
+ "render": props.content
2457
+ }, null) : null, slots.default?.()]), props.footer && (props.cancelText || props.okText) && vue.createVNode("div", {
2458
+ "class": ['vc-drawer__footer']
2459
+ }, [slots['footer-extra']?.(), !slots.footer ? vue.createVNode(vue.Fragment, null, [props.cancelText && vue.createVNode(Button, {
2460
+ "style": "margin-right: 8px;",
2461
+ "onClick": e => handleBefore(e, handleCancel)
2462
+ }, {
2463
+ default: () => [props.cancelText]
2464
+ }), props.okText && vue.createVNode(Button, {
2465
+ "type": "primary",
2466
+ "onClick": e => handleBefore(e, handleOk)
2467
+ }, {
2468
+ default: () => [props.okText]
2469
+ })]) : slots.footer?.()])])]), [[vue.vShow, isActive.value]])) ? _slot2 : {
2470
+ default: () => [_slot2]
2471
+ })]);
2472
+ };
2473
+ }
2474
+ });
2475
+
2476
+ const Drawer = new Portal(DrawerView, {
2477
+ leaveDelay: 0,
2478
+ multiple: true
2479
+ });
2480
+ const destroy$5 = () => Drawer.destroy();
2481
+ const open$1 = (options) => {
2482
+ const leaf = Drawer.popup({
2483
+ ...options,
2484
+ onFulfilled: options.onClose,
2485
+ // 当组件内使用emit('close'),避免重复触发
2486
+ onClose: null
2209
2487
  });
2210
- return {
2211
- isNest,
2212
- isStyleless,
2213
- isNestLast,
2214
- validateMessage,
2215
- classes,
2216
- labelStyle,
2217
- contentStyle,
2218
- showError,
2219
- labelPosition
2220
- };
2488
+ leaf.wrapper.toggle?.(true);
2489
+ return leaf;
2490
+ };
2491
+
2492
+ const drawer = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
2493
+ __proto__: null,
2494
+ destroy: destroy$5,
2495
+ open: open$1
2496
+ }, Symbol.toStringTag, { value: 'Module' }));
2497
+
2498
+ const MDrawerView = DrawerView;
2499
+
2500
+ const props$V = {
2501
+ tag: {
2502
+ type: String,
2503
+ default: "div"
2504
+ }
2221
2505
  };
2222
2506
 
2223
2507
  /** @jsxImportSource vue */
2224
2508
 
2225
- const COMPONENT_NAME$11 = 'vc-form-item';
2226
- const FormItem = /* @__PURE__ */ vue.defineComponent({
2227
- name: COMPONENT_NAME$11,
2228
- props: props$S,
2509
+ const COMPONENT_NAME$14 = 'vc-dropdown';
2510
+ const Dropdown = /* @__PURE__ */ vue.defineComponent({
2511
+ name: COMPONENT_NAME$14,
2512
+ props: props$V,
2229
2513
  setup(props, {
2230
- slots,
2231
- expose
2514
+ slots
2232
2515
  }) {
2233
- const it = useFormItem(expose);
2234
- const {
2235
- isStyleless,
2236
- isNest,
2237
- classes,
2238
- labelStyle,
2239
- contentStyle,
2240
- showError,
2241
- validateMessage
2242
- } = it;
2243
- const {
2244
- label,
2245
- labelFor
2246
- } = props;
2247
- const errorColorClass = 'vc-form-item__error';
2248
2516
  return () => {
2249
- if (isStyleless.value) return [slots.default?.(), slots.error?.({
2250
- show: showError.value,
2251
- nest: isNest.value,
2252
- message: validateMessage.value,
2253
- class: errorColorClass
2254
- })];
2255
2517
  return vue.createVNode("div", {
2256
- "class": ['vc-form-item', classes.value]
2257
- }, [vue.createVNode("div", {
2258
- "style": labelStyle.value,
2259
- "class": "vc-form-item__label",
2260
- "for": labelFor
2261
- }, [vue.createVNode("label", null, [label || slots.label?.()])]), vue.createVNode("div", {
2262
- "class": "vc-form-item__wrapper"
2263
- }, [vue.createVNode("div", {
2264
- "class": "vc-form-item__content",
2265
- "style": contentStyle.value
2266
- }, [slots.default?.(), slots.error ? slots.error({
2267
- show: showError.value,
2268
- nest: isNest.value,
2269
- message: validateMessage.value,
2270
- class: errorColorClass
2271
- }) : vue.createVNode(TransitionFade, null, {
2272
- default: () => [vue.withDirectives(vue.createVNode("div", {
2273
- "class": ['vc-form-item__tip', isNest.value ? 'is-nest' : '', errorColorClass]
2274
- }, [validateMessage.value]), [[vue.vShow, showError.value]])]
2275
- })])])]);
2518
+ "class": "vc-dropdown"
2519
+ }, [slots?.default?.()]);
2276
2520
  };
2277
2521
  }
2278
2522
  });
2279
2523
 
2280
- const props$R = {
2281
- ...props$T,
2282
- showToast: {
2283
- type: Boolean,
2284
- default: false
2285
- },
2286
- border: {
2287
- type: Boolean,
2288
- default: false
2524
+ const MDropdown = Dropdown;
2525
+
2526
+ const props$U = {
2527
+ tag: {
2528
+ type: String,
2529
+ default: "div"
2289
2530
  }
2290
2531
  };
2291
2532
 
2292
- const props$Q = {
2293
- content: [String, Function],
2294
- maskClosable: {
2533
+ /** @jsxImportSource vue */
2534
+
2535
+ const COMPONENT_NAME$13 = 'vc-editor';
2536
+ const Editor = /* @__PURE__ */ vue.defineComponent({
2537
+ name: COMPONENT_NAME$13,
2538
+ props: props$U,
2539
+ setup(props, {
2540
+ slots
2541
+ }) {
2542
+ return () => {
2543
+ return vue.createVNode("div", {
2544
+ "class": "vc-editor"
2545
+ }, [slots?.default?.()]);
2546
+ };
2547
+ }
2548
+ });
2549
+
2550
+ const MEditor = Editor;
2551
+
2552
+ const MExpand = Expand;
2553
+
2554
+ const props$T = {
2555
+ tag: {
2556
+ type: String,
2557
+ default: "form"
2558
+ },
2559
+ model: {
2560
+ type: Object
2561
+ },
2562
+ rules: {
2563
+ type: Object
2564
+ },
2565
+ labelWidth: {
2566
+ type: Number
2567
+ },
2568
+ showMessage: {
2295
2569
  type: Boolean,
2296
2570
  default: true
2297
2571
  },
2298
- duration: {
2299
- type: Number,
2300
- default: 3e3
2572
+ inline: {
2573
+ type: Boolean,
2574
+ default: false
2301
2575
  },
2302
- mode: {
2576
+ labelPosition: {
2303
2577
  type: String,
2304
- default: "info",
2305
- validator: (val) => ["info", "loading", "success", "warning", "error"].includes(val)
2578
+ default: "right"
2579
+ },
2580
+ autocomplete: {
2581
+ type: String,
2582
+ default: "off"
2583
+ },
2584
+ styleless: {
2585
+ type: Boolean,
2586
+ default: false
2306
2587
  }
2307
2588
  };
2308
2589
 
2309
- const MSpin = Spin;
2310
-
2311
- const MTransition = Transition;
2312
- const MTransitionCollapse = TransitionCollapse;
2313
- const MTransitionFade = TransitionFade;
2314
- const MTransitionScale = TransitionScale;
2315
- const MTransitionSlide = TransitionSlide;
2316
- const MTransitionZoom = TransitionZoom;
2317
-
2318
- /** @jsxImportSource vue */
2319
-
2320
- const COMPONENT_NAME$10 = 'vcm-toast';
2321
- const MToastView = /* @__PURE__ */ vue.defineComponent({
2322
- name: COMPONENT_NAME$10,
2323
- emits: ['close', 'portal-fulfilled'],
2324
- props: props$Q,
2325
- setup(props, {
2326
- emit,
2327
- expose
2328
- }) {
2329
- const isVisible = vue.ref(false);
2330
-
2331
- // 兼容Portal设计
2332
- const handleRemove = () => {
2333
- emit('close');
2334
- emit('portal-fulfilled');
2335
- };
2336
- const handleClose = () => {
2337
- if (props.maskClosable) {
2338
- isVisible.value = false;
2339
- }
2340
- };
2341
- let timer;
2342
- vue.onMounted(() => {
2343
- isVisible.value = true;
2344
- if (props.duration !== 0) {
2345
- timer = setTimeout(() => {
2346
- // 主线程
2347
- isVisible.value = false;
2348
- }, props.duration - 300); // 动画时间
2349
- }
2590
+ const useForm = (expose, options = {}) => {
2591
+ const instance = vue.getCurrentInstance();
2592
+ const props = instance.props;
2593
+ const fields = [];
2594
+ vue.provide("form", {
2595
+ props,
2596
+ add: (field) => {
2597
+ field && fields.push(field);
2598
+ },
2599
+ remove: (field) => {
2600
+ field && fields.splice(fields.indexOf(field), 1);
2601
+ }
2602
+ });
2603
+ const filterFields = (fields$) => {
2604
+ return !fields$ ? fields : fields.filter((item) => fields$.includes(item.props.prop));
2605
+ };
2606
+ const getField = (prop) => {
2607
+ const field = fields.find((item) => item.props.prop === prop);
2608
+ if (!field) throw new VcError("form", "请选择有用的prop值");
2609
+ return field;
2610
+ };
2611
+ const showToast = (msg) => {
2612
+ props.showMessage && options.throwToast?.(msg);
2613
+ };
2614
+ const sortErrors = async (errors) => {
2615
+ const positions = await Promise.all(fields.map((item) => item.exposed.getPosition()));
2616
+ try {
2617
+ return [...errors].toSorted((a, b) => {
2618
+ const aIndex = fields.findIndex((i) => i.props.prop === a.prop);
2619
+ const bIndex = fields.findIndex((i) => i.props.prop === b.prop);
2620
+ const aPosition = positions[aIndex];
2621
+ const bPosition = positions[bIndex];
2622
+ if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
2623
+ return aPosition.left - bPosition.left;
2624
+ });
2625
+ } catch {
2626
+ return errors;
2627
+ }
2628
+ };
2629
+ const scrollIntoView = (prop) => {
2630
+ const field = getField(prop);
2631
+ field.vnode?.el?.scrollIntoView?.({
2632
+ behavior: "smooth",
2633
+ block: "center"
2350
2634
  });
2351
- vue.onUnmounted(() => {
2352
- timer && clearTimeout(timer);
2635
+ };
2636
+ const reset = (options$ = {}) => {
2637
+ const { fields: fields$, original = {} } = options$;
2638
+ filterFields(fields$).forEach((field) => {
2639
+ let v;
2640
+ try {
2641
+ v = Utils.getPropByPath(original, field.props.prop).v;
2642
+ } catch {
2643
+ }
2644
+ field.exposed.reset(v);
2353
2645
  });
2354
- const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
2355
- pre[key] = handleRemove;
2356
- return pre;
2357
- }, {});
2358
- expose(exposes);
2646
+ };
2647
+ const validate = async (options$ = {}) => {
2648
+ const { scroll = true, fields: fields$ } = options$;
2649
+ if (!fields.length) {
2650
+ return;
2651
+ }
2652
+ const results = await Promise.allSettled(
2653
+ filterFields(fields$).map((item) => item.exposed.validate(""))
2654
+ );
2655
+ const originErrors = results.filter((i) => i.status === "rejected").map((i) => i.reason);
2656
+ if (!originErrors.length) return;
2657
+ const errors = await sortErrors(originErrors);
2658
+ showToast(errors[0].msg || errors[0].message);
2659
+ scroll && scrollIntoView(errors[0].prop);
2660
+ throw errors;
2661
+ };
2662
+ const validateField = async (prop, options$ = {}) => {
2663
+ try {
2664
+ await validate({
2665
+ ...options$,
2666
+ fields: [prop]
2667
+ });
2668
+ } catch (e) {
2669
+ throw e[0];
2670
+ }
2671
+ };
2672
+ expose({
2673
+ reset,
2674
+ validate,
2675
+ // 单个操作
2676
+ getField,
2677
+ validateField
2678
+ });
2679
+ };
2680
+
2681
+ const COMPONENT_NAME$12 = "vc-form";
2682
+ const Form = vue.defineComponent({
2683
+ name: COMPONENT_NAME$12,
2684
+ props: props$T,
2685
+ setup(props, { slots, expose }) {
2686
+ useForm(expose);
2359
2687
  return () => {
2360
- return vue.createVNode("div", {
2361
- "class": "vcm-toast"
2362
- }, [vue.createVNode("div", {
2363
- "class": "vcm-toast__bg",
2364
- "onClick": handleClose,
2365
- "onTouchmove": vue.withModifiers(() => {}, ['prevent'])
2366
- }, null), vue.createVNode(MTransitionFade, {
2367
- "duration": {
2368
- enter: 300,
2369
- leave: 150
2688
+ return vue.h(
2689
+ props.tag,
2690
+ {
2691
+ class: "vc-form",
2692
+ autocomplete: props.autocomplete
2370
2693
  },
2371
- "onAfterLeave": handleRemove
2372
- }, {
2373
- default: () => [vue.withDirectives(vue.createVNode("div", {
2374
- "class": "vcm-toast__wrapper"
2375
- }, [props.mode === 'loading' && vue.createVNode(MSpin, {
2376
- "class": "vcm-toast__loading"
2377
- }, null), typeof props.content === 'string' ? vue.createVNode("div", {
2378
- "class": "vcm-toast__content",
2379
- "innerHTML": props.content
2380
- }, null) : typeof props.content === 'function' ? vue.createVNode(MCustomer, {
2381
- "render": props.content
2382
- }, null) : null]), [[vue.vShow, isVisible.value]])]
2383
- })]);
2694
+ slots
2695
+ );
2384
2696
  };
2385
2697
  }
2386
2698
  });
2387
2699
 
2388
- const defaults = {
2389
- tag: "div",
2390
- el: "body",
2391
- alive: false,
2392
- multiple: false,
2393
- aliveRegExp: { className: /(vc-hack-alive|vc-hack-cp)/ },
2394
- aliveVisibleKey: "isVisible",
2395
- aliveUpdateKey: "update",
2396
- leaveDelay: 300,
2397
- autoDestroy: true,
2398
- components: {},
2399
- uses: {},
2400
- fragment: false,
2401
- insertion: "last"
2700
+ const props$S = {
2701
+ label: {
2702
+ type: String,
2703
+ default: ""
2704
+ },
2705
+ labelWidth: {
2706
+ type: Number
2707
+ },
2708
+ prop: {
2709
+ type: String
2710
+ },
2711
+ required: {
2712
+ type: [Boolean, String],
2713
+ default: false
2714
+ },
2715
+ // 控制`*`是否展示
2716
+ asterisk: {
2717
+ type: Boolean,
2718
+ default: true
2719
+ },
2720
+ error: {
2721
+ type: String
2722
+ },
2723
+ rules: {
2724
+ type: [Array, Object]
2725
+ },
2726
+ resetByRulesChanged: {
2727
+ type: Boolean,
2728
+ default: false
2729
+ },
2730
+ showMessage: {
2731
+ type: Boolean,
2732
+ default: true
2733
+ },
2734
+ labelFor: {
2735
+ type: String
2736
+ },
2737
+ styleless: {
2738
+ type: Boolean,
2739
+ default: false
2740
+ },
2741
+ labelPosition: {
2742
+ type: String,
2743
+ default: "right"
2744
+ },
2745
+ contentStyle: String
2402
2746
  };
2403
2747
 
2404
- class PortalLeaf {
2405
- app;
2406
- /**
2407
- * 目标的实例,挂载到app上
2408
- */
2409
- wrapper;
2410
- propsData;
2411
- /**
2412
- * 销毁的函数,挂载到app上,避免冲突
2413
- */
2414
- destroy;
2415
- /**
2416
- * 自动销毁的标记,挂载到app上,避免冲突
2417
- */
2418
- autoDestroy;
2419
- target;
2420
- constructor(target) {
2421
- this.target = target;
2422
- this.autoDestroy = false;
2423
- this.destroy = /* istanbul ignore next */
2424
- () => {
2425
- throw new VcError("portal", "未注册的destroy方法");
2426
- };
2427
- }
2428
- then(resolve, reject) {
2429
- return this.target.then(resolve, reject);
2430
- }
2431
- catch(callback) {
2432
- return this.target.catch(callback);
2748
+ const filterEmpty = (val) => {
2749
+ if (val instanceof Array) {
2750
+ val = val.filter((i) => i !== "");
2433
2751
  }
2434
- finally(callback) {
2435
- return this.target.finally(callback);
2752
+ return val;
2753
+ };
2754
+ const toRules = (rules) => {
2755
+ return rules instanceof Array ? rules : rules ? [rules] : [];
2756
+ };
2757
+ const useFormItem = (expose) => {
2758
+ const form = vue.inject("form");
2759
+ const instance = vue.getCurrentInstance();
2760
+ const props = instance.props;
2761
+ const { slots } = instance;
2762
+ if (!form?.props) {
2763
+ throw new VcError("form-item", "form-item需要在form内使用");
2436
2764
  }
2437
- }
2438
-
2439
- const COMPONENT_NAME$$ = "vc-portal";
2440
- class Portal {
2441
- /**
2442
- * 清理Portals类型组件
2443
- * @param name 清理的组件名, boolean表示全部leafs是否强制清理
2444
- */
2445
- static clear(name) {
2446
- try {
2447
- let force = false;
2448
- let target = /* @__PURE__ */ new Map();
2449
- if (name && typeof name !== "boolean") {
2450
- let names = [];
2451
- if (typeof name === "string") {
2452
- names = [name];
2453
- } else if (name instanceof Array && name.length > 0) {
2454
- names = name;
2455
- }
2456
- names.forEach((i) => target.set(i, ""));
2457
- force = true;
2458
- } else {
2459
- force = !!name;
2460
- target = Portal.leafs;
2461
- }
2462
- for (const key of target.keys()) {
2463
- const leaf = Portal.leafs.get(key);
2464
- if (leaf && (force === true || leaf.autoDestroy === true)) {
2465
- leaf.destroy();
2466
- }
2765
+ const formItem = vue.inject("vc-form-item", {});
2766
+ const validateState = vue.ref("");
2767
+ const validateMessage = vue.ref("");
2768
+ let validateDisabled = false;
2769
+ let initialValue;
2770
+ const currentRules = vue.computed(() => {
2771
+ const formRules = form.props.rules;
2772
+ const formItemBindRules = toRules(props.rules);
2773
+ let formItemRules = formItemBindRules;
2774
+ if (!formItemRules.length && formRules && props.prop) {
2775
+ try {
2776
+ const key = props.prop.replace(/\.[0-9]+\./g, ".");
2777
+ const { v } = Utils.getPropByPath(formRules, key);
2778
+ formItemRules = toRules(v);
2779
+ } catch {
2780
+ const rules = formRules[props.prop];
2781
+ formItemRules = toRules(rules);
2467
2782
  }
2468
- } catch (e) {
2469
- /* istanbul ignore next -- @preserve */
2470
- throw new VcError("instance", e);
2471
- }
2472
- }
2473
- /**
2474
- * 清理全部Portals
2475
- */
2476
- static clearAll() {
2477
- try {
2478
- Portal.leafs.forEach((leaf) => leaf.destroy());
2479
- } catch (e) {
2480
- /* istanbul ignore next -- @preserve */
2481
- throw new VcError("instance", e);
2482
- }
2483
- }
2484
- static leafs = /* @__PURE__ */ new Map();
2485
- wrapper;
2486
- globalOptions;
2487
- constructor(wrapper, options) {
2488
- this.wrapper = wrapper;
2489
- this.globalOptions = {
2490
- ...options,
2491
- name: options?.name || wrapper.name || Utils__namespace.getUid(COMPONENT_NAME$$)
2492
- };
2493
- }
2494
- popup(propsData, options) {
2495
- if (!options) {
2496
- options = propsData || {};
2497
- } else {
2498
- options.propsData = propsData;
2499
2783
  }
2500
- const $options = { ...this.getDefaultOptions(), ...options };
2501
- const { onFulfilled, onRejected, ...rest } = $options;
2502
- let onFulfilled$ = (
2503
- /* istanbul ignore next -- @preserve */
2504
- () => {
2505
- }
2506
- );
2507
- let onRejected$ = (
2508
- /* istanbul ignore next -- @preserve */
2509
- () => {
2510
- }
2511
- );
2512
- const target = new Promise((resolve, reject) => {
2513
- onFulfilled$ = (v) => {
2514
- onFulfilled?.(v);
2515
- resolve(v);
2516
- };
2517
- onRejected$ = (v) => {
2518
- onRejected?.(v);
2519
- reject(v);
2520
- };
2521
- });
2522
- return this.render(rest, target, onFulfilled$, onRejected$);
2523
- }
2524
- /**
2525
- * 销毁当前Portal下的节点
2526
- * @param target [description]
2527
- */
2528
- destroy = (target) => {
2529
- const { multiple, name } = this.getDefaultOptions();
2530
- target = target || name;
2531
- const instance = typeof target === "object" ? target : Portal.leafs.get(target);
2532
- if (instance) {
2533
- instance.destroy();
2534
- } else if (multiple) {
2535
- Portal.leafs.forEach((item, key) => {
2536
- if (key.includes(name)) {
2537
- item.destroy();
2538
- }
2539
- });
2784
+ return formItemRules;
2785
+ });
2786
+ const isRequired = vue.computed(() => {
2787
+ if (!currentRules.value.length) {
2788
+ return !!props.required;
2540
2789
  }
2541
- };
2542
- getDefaultOptions() {
2790
+ let required = false;
2791
+ for (let i = 0; i < currentRules.value.length; i++) {
2792
+ const rule = currentRules.value[i];
2793
+ required = !!rule.required;
2794
+ if (required) break;
2795
+ }
2796
+ return required;
2797
+ });
2798
+ const labelPosition = vue.computed(() => {
2799
+ return props.labelPosition || form.props.labelPosition;
2800
+ });
2801
+ const classes = vue.computed(() => {
2543
2802
  return {
2544
- ...defaults,
2545
- ...VcInstance.options.Portal,
2546
- ...this.globalOptions
2547
- };
2548
- }
2549
- createCallback(getLeaf, delay, callback) {
2550
- return (...args) => {
2551
- const done = () => {
2552
- const leaf = getLeaf();
2553
- /* istanbul ignore next -- @preserve */
2554
- if (!leaf) {
2555
- throw new VcError("portal", "实例不存在或已卸载");
2556
- }
2557
- leaf.destroy();
2558
- };
2559
- delay ? setTimeout(done, delay) : done();
2560
- callback?.(...args);
2561
- };
2562
- }
2563
- render(options, target, onFulfilled, onRejected) {
2564
- const {
2565
- el,
2566
- tag,
2567
- alive,
2568
- aliveRegExp,
2569
- aliveVisibleKey,
2570
- aliveUpdateKey,
2571
- name: name$,
2572
- leaveDelay,
2573
- autoDestroy,
2574
- multiple,
2575
- fragment,
2576
- onDestroyed,
2577
- onBeforeCreate,
2578
- insertion,
2579
- // 全局注册
2580
- globalProperties,
2581
- install,
2582
- components,
2583
- uses,
2584
- slots,
2585
- parent,
2586
- propsData,
2587
- ...rest
2588
- } = options;
2589
- let useAllNodes = fragment;
2590
- const name = multiple ? `${name$}__${Utils__namespace.getUid(COMPONENT_NAME$$)}` : name$;
2591
- const container = document.createElement(tag);
2592
- const root = typeof el === "object" ? el : document.querySelector(el || "body");
2593
- !alive && Portal.leafs.get(name)?.destroy();
2594
- const propsData$ = propsData || rest;
2595
- let leaf = new PortalLeaf(target);
2596
- const isDestroyed = () => {
2597
- const leaf$ = Portal.leafs.get(name);
2598
- return !leaf$ || leaf$ !== leaf;
2803
+ "is-require": isRequired.value && props.asterisk,
2804
+ "is-error": validateState.value === "error",
2805
+ "is-validating": validateState.value === "validating",
2806
+ "is-inline": form.props.inline,
2807
+ "is-nest": isNest.value,
2808
+ [`is-${labelPosition.value}`]: true
2599
2809
  };
2600
- const $onDestroyed = (...args) => {
2601
- if (isDestroyed()) return;
2602
- onDestroyed?.(...args);
2603
- leaf.app?.unmount();
2604
- /* istanbul ignore else -- @preserve */
2605
- if (useAllNodes) {
2606
- root?.contains(container) && root.removeChild(container);
2607
- } else if (container && container._children) {
2608
- container._children.forEach((i) => {
2609
- root?.contains(i) && root.removeChild(i);
2610
- });
2611
- }
2612
- Portal.leafs.delete(name);
2810
+ });
2811
+ const isNest = vue.computed(() => {
2812
+ return !!formItem.change;
2813
+ });
2814
+ const isNestLast = vue.ref(false);
2815
+ const hasLabel = vue.computed(() => {
2816
+ return !!props.label || slots.label;
2817
+ });
2818
+ const labelStyle = vue.computed(() => {
2819
+ const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNest.value ? 0 : form.props.labelWidth;
2820
+ return {
2821
+ width: labelPosition.value !== "top" && labelWidth && labelWidth > 0 ? `${labelWidth}px` : "auto",
2822
+ textAlign: labelPosition.value === "top" ? "left" : labelPosition.value
2613
2823
  };
2614
- const $onRejected = this.createCallback(() => leaf, leaveDelay, onRejected);
2615
- const $onFulfilled = this.createCallback(() => leaf, leaveDelay, onFulfilled);
2616
- if (alive && Portal.leafs.has(name)) {
2617
- leaf = Portal.leafs.get(name);
2618
- leaf.target = target;
2619
- leaf.propsData.value = propsData$;
2620
- leaf.wrapper?.[aliveUpdateKey]?.(options);
2621
- } else {
2622
- const wrapper = this.wrapper;
2623
- const app = vue.createApp({
2624
- name: COMPONENT_NAME$$,
2625
- parent,
2626
- setup() {
2627
- if (alive) {
2628
- const handleExtra = (e) => {
2629
- try {
2630
- const path = e.path || $__namespace.composedPath(e);
2631
- /* istanbul ignore else -- @preserve */
2632
- if (container && e.target && !container.contains(e.target) && !path?.some((item) => vcShared.Utils.eleInRegExp(item, aliveRegExp))) {
2633
- /* istanbul ignore else -- @preserve */
2634
- if (leaf.wrapper && leaf.wrapper?.[aliveVisibleKey]) {
2635
- leaf.wrapper[aliveVisibleKey] = false;
2636
- }
2637
- leaveDelay ? setTimeout($onDestroyed, leaveDelay) : $onDestroyed();
2638
- }
2639
- } catch (error) {
2640
- /* istanbul ignore next -- @preserve */
2641
- throw new VcError("portal", error);
2642
- }
2643
- };
2644
- vue.onMounted(() => {
2645
- document.addEventListener("click", handleExtra, true);
2646
- });
2647
- vue.onBeforeUnmount(() => {
2648
- document.removeEventListener("click", handleExtra, true);
2649
- });
2650
- }
2651
- const propsData1 = vue.ref(propsData$);
2652
- const propsData2 = vue.ref();
2653
- leaf.propsData = propsData1;
2654
- const allowMounted = vue.ref(typeof onBeforeCreate !== "function");
2655
- if (!allowMounted.value) {
2656
- const result = onBeforeCreate(propsData$);
2657
- if (result && result.then) {
2658
- result.then((response) => {
2659
- if (isDestroyed()) return;
2660
- allowMounted.value = true;
2661
- propsData2.value = response;
2662
- }).catch((error) => {
2663
- $onDestroyed(error);
2664
- });
2665
- } else {
2666
- allowMounted.value = true;
2667
- propsData2.value = result;
2668
- }
2669
- }
2670
- return () => allowMounted.value && vue.h(
2671
- wrapper,
2672
- {
2673
- ...propsData1.value,
2674
- ...propsData2.value,
2675
- ref: (vm) => leaf.wrapper = vm,
2676
- onPortalFulfilled: (...args) => $onFulfilled(...args),
2677
- onPortalRejected: (...args) => $onRejected(...args),
2678
- onPortalDestroyed: (...args) => $onDestroyed(...args)
2679
- },
2680
- slots || void 0
2681
- );
2682
- }
2683
- });
2684
- leaf.app = app;
2685
- if (globalProperties) {
2686
- app.config.globalProperties = globalProperties;
2687
- }
2688
- for (const key in components) {
2689
- app.component(key, components[key]);
2690
- }
2691
- for (const key in uses) {
2692
- app.use(uses[key]);
2824
+ });
2825
+ const contentStyle = vue.computed(() => {
2826
+ const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : form.props.labelWidth;
2827
+ return [
2828
+ {
2829
+ marginLeft: !hasLabel.value && isNest.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
2830
+ marginBottom: isNest.value && !isNestLast.value ? `20px` : 0
2831
+ },
2832
+ props.contentStyle
2833
+ ];
2834
+ });
2835
+ const isStyleless = vue.computed(() => {
2836
+ return props.styleless || form.props.styleless;
2837
+ });
2838
+ const fieldValue = vue.computed(() => {
2839
+ const model = form.props.model;
2840
+ if (!model || !props.prop) {
2841
+ return;
2842
+ }
2843
+ let path = props.prop;
2844
+ if (path.includes(":")) {
2845
+ path = path.replace(/:/, ".");
2846
+ }
2847
+ return Utils.getPropByPath(model, path).v;
2848
+ });
2849
+ const showError = vue.computed(() => {
2850
+ return validateState.value === "error" && props.showMessage && form.props.showMessage;
2851
+ });
2852
+ vue.watch(
2853
+ () => props.error,
2854
+ (v) => {
2855
+ validateMessage.value = v || "";
2856
+ validateState.value = v === "" ? "" : "error";
2857
+ }
2858
+ );
2859
+ const reset = (v) => {
2860
+ validateState.value = "";
2861
+ validateMessage.value = "";
2862
+ const model = form.props.model;
2863
+ if (!props.prop) return;
2864
+ const { o, k } = Utils.getPropByPath(model, props.prop);
2865
+ if (!k) return;
2866
+ validateDisabled = true;
2867
+ o[k] = v !== null && v !== void 0 ? v : Array.isArray(fieldValue.value) ? [].concat(initialValue) : initialValue;
2868
+ };
2869
+ const validate = async (trigger) => {
2870
+ if (!props.prop) return;
2871
+ let rules = currentRules.value.filter((rule) => !rule.trigger || rule.trigger.includes(trigger));
2872
+ if (!rules.length) {
2873
+ if (!props.required) {
2874
+ return;
2875
+ } else {
2876
+ rules = [{
2877
+ required: true,
2878
+ message: typeof props.required === "string" ? props.required : void 0
2879
+ }];
2693
2880
  }
2694
- install?.(app);
2695
- app.mount(container);
2696
2881
  }
2697
- leaf.destroy = $onDestroyed;
2698
- leaf.autoDestroy = !!autoDestroy;
2699
- Portal.leafs.set(name, leaf);
2700
- const append = (root$, child$) => {
2701
- if (!root$ || !child$) return;
2702
- if (insertion === "first") {
2703
- const firstEl = root$.firstElementChild;
2704
- if (firstEl) {
2705
- root$.insertBefore(child$, firstEl);
2706
- return;
2707
- }
2708
- }
2709
- root$.appendChild(child$);
2710
- };
2711
- if (fragment || typeof container._children === "undefined" && !Array.from(container.children).length) {
2712
- useAllNodes = true;
2713
- container.parentElement === null && append(root, container);
2714
- } else if (!container._children) {
2715
- container._children = [];
2716
- let childs = Array.from(container.children);
2717
- if (insertion === "first") {
2718
- childs = childs.reverse();
2882
+ validateState.value = "validating";
2883
+ const descriptor = {};
2884
+ descriptor[props.prop] = rules;
2885
+ const validator = new helperValidator.Validator(descriptor);
2886
+ const model = {};
2887
+ model[props.prop] = filterEmpty(fieldValue.value);
2888
+ try {
2889
+ await validator.validate(model, { first: false });
2890
+ validateState.value = "success";
2891
+ validateMessage.value = "";
2892
+ } catch (errors) {
2893
+ validateState.value = "error";
2894
+ validateMessage.value = errors[0].message;
2895
+ throw {
2896
+ prop: props.prop,
2897
+ message: validateMessage.value
2898
+ };
2899
+ }
2900
+ validateDisabled = false;
2901
+ };
2902
+ const handleFieldBlur = () => {
2903
+ if (!props.prop) {
2904
+ formItem.blur?.();
2905
+ return;
2906
+ }
2907
+ validate("blur");
2908
+ };
2909
+ const handleFieldChange = () => {
2910
+ if (!props.prop) {
2911
+ formItem.change?.();
2912
+ return;
2913
+ }
2914
+ if (validateDisabled) {
2915
+ validateDisabled = false;
2916
+ return;
2917
+ }
2918
+ validate("change");
2919
+ };
2920
+ const getPosition = async () => {
2921
+ let el = instance.vnode.el;
2922
+ try {
2923
+ while (el && !el.getBoundingClientRect) {
2924
+ el = el.nextSibling;
2719
2925
  }
2720
- childs.forEach((i) => {
2721
- append(root, i);
2722
- container._children?.push?.(i);
2926
+ ;
2927
+ const rect = el.getBoundingClientRect();
2928
+ return {
2929
+ top: rect.top,
2930
+ left: rect.left
2931
+ };
2932
+ } catch {
2933
+ throw new VcError("form-item", "form-item位置计算错误");
2934
+ }
2935
+ };
2936
+ const fields = vue.reactive([]);
2937
+ vue.provide("vc-form-item", {
2938
+ fields,
2939
+ blur: handleFieldBlur,
2940
+ change: handleFieldChange,
2941
+ message: validateMessage,
2942
+ add: (field) => {
2943
+ field && fields.push(field);
2944
+ },
2945
+ remove: (field) => {
2946
+ field && fields.splice(fields.indexOf(field), 1);
2947
+ }
2948
+ });
2949
+ vue.onMounted(() => {
2950
+ if (props.prop) {
2951
+ form.add?.(instance);
2952
+ initialValue = lodashEs.cloneDeep(fieldValue.value);
2953
+ }
2954
+ formItem.add?.(instance);
2955
+ });
2956
+ vue.onBeforeUnmount(() => {
2957
+ form.remove?.(instance);
2958
+ formItem.remove?.(instance);
2959
+ });
2960
+ vue.watch(
2961
+ () => props.rules,
2962
+ () => {
2963
+ props.resetByRulesChanged && reset();
2964
+ }
2965
+ );
2966
+ vue.watch(
2967
+ () => formItem.fields?.length,
2968
+ async (v) => {
2969
+ if (!isNest.value || !v) return isNestLast.value = false;
2970
+ const fields$ = [...vue.toRaw(formItem.fields)];
2971
+ const positions = await Promise.all(fields$.map((item) => item.exposed.getPosition()));
2972
+ const sortFields = fields$.toSorted((a, b) => {
2973
+ const aIndex = fields$.findIndex((i) => i === a);
2974
+ const bIndex = fields$.findIndex((i) => i === b);
2975
+ const aPosition = positions[aIndex];
2976
+ const bPosition = positions[bIndex];
2977
+ if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
2978
+ return aPosition.left - bPosition.left;
2723
2979
  });
2980
+ isNestLast.value = sortFields[sortFields.length - 1] === instance;
2724
2981
  }
2725
- return leaf;
2982
+ );
2983
+ expose({
2984
+ validate,
2985
+ reset,
2986
+ getPosition
2987
+ });
2988
+ return {
2989
+ isNest,
2990
+ isStyleless,
2991
+ isNestLast,
2992
+ validateMessage,
2993
+ classes,
2994
+ labelStyle,
2995
+ contentStyle,
2996
+ showError,
2997
+ labelPosition
2998
+ };
2999
+ };
3000
+
3001
+ /** @jsxImportSource vue */
3002
+
3003
+ const COMPONENT_NAME$11 = 'vc-form-item';
3004
+ const FormItem = /* @__PURE__ */ vue.defineComponent({
3005
+ name: COMPONENT_NAME$11,
3006
+ props: props$S,
3007
+ setup(props, {
3008
+ slots,
3009
+ expose
3010
+ }) {
3011
+ const it = useFormItem(expose);
3012
+ const {
3013
+ isStyleless,
3014
+ isNest,
3015
+ classes,
3016
+ labelStyle,
3017
+ contentStyle,
3018
+ showError,
3019
+ validateMessage
3020
+ } = it;
3021
+ const {
3022
+ label,
3023
+ labelFor
3024
+ } = props;
3025
+ const errorColorClass = 'vc-form-item__error';
3026
+ return () => {
3027
+ if (isStyleless.value) return [slots.default?.(), slots.error?.({
3028
+ show: showError.value,
3029
+ nest: isNest.value,
3030
+ message: validateMessage.value,
3031
+ class: errorColorClass
3032
+ })];
3033
+ return vue.createVNode("div", {
3034
+ "class": ['vc-form-item', classes.value]
3035
+ }, [vue.createVNode("div", {
3036
+ "style": labelStyle.value,
3037
+ "class": "vc-form-item__label",
3038
+ "for": labelFor
3039
+ }, [vue.createVNode("label", null, [label || slots.label?.()])]), vue.createVNode("div", {
3040
+ "class": "vc-form-item__wrapper"
3041
+ }, [vue.createVNode("div", {
3042
+ "class": "vc-form-item__content",
3043
+ "style": contentStyle.value
3044
+ }, [slots.default?.(), slots.error ? slots.error({
3045
+ show: showError.value,
3046
+ nest: isNest.value,
3047
+ message: validateMessage.value,
3048
+ class: errorColorClass
3049
+ }) : vue.createVNode(TransitionFade, null, {
3050
+ default: () => [vue.withDirectives(vue.createVNode("div", {
3051
+ "class": ['vc-form-item__tip', isNest.value ? 'is-nest' : '', errorColorClass]
3052
+ }, [validateMessage.value]), [[vue.vShow, showError.value]])]
3053
+ })])])]);
3054
+ };
2726
3055
  }
2727
- }
3056
+ });
2728
3057
 
2729
- const props$P = {
2730
- tag: {
3058
+ const props$R = {
3059
+ ...props$T,
3060
+ showToast: {
3061
+ type: Boolean,
3062
+ default: false
3063
+ },
3064
+ border: {
3065
+ type: Boolean,
3066
+ default: false
3067
+ }
3068
+ };
3069
+
3070
+ const props$Q = {
3071
+ content: [String, Function],
3072
+ maskClosable: {
3073
+ type: Boolean,
3074
+ default: true
3075
+ },
3076
+ // 单位ms
3077
+ duration: {
3078
+ type: Number,
3079
+ default: 3e3
3080
+ },
3081
+ mode: {
2731
3082
  type: String,
2732
- default: "div"
3083
+ default: "info",
3084
+ validator: (val) => ["info", "loading", "success", "warning", "error"].includes(val)
2733
3085
  }
2734
3086
  };
2735
3087
 
2736
- const COMPONENT_NAME$_ = 'vc-portal-view';
3088
+ const MSpin = Spin;
3089
+
3090
+ const MTransition = Transition;
3091
+ const MTransitionCollapse = TransitionCollapse;
3092
+ const MTransitionFade = TransitionFade;
3093
+ const MTransitionScale = TransitionScale;
3094
+ const MTransitionSlide = TransitionSlide;
3095
+ const MTransitionZoom = TransitionZoom;
2737
3096
 
2738
- /**
2739
- * 写法不同,但与vue@2.x 保持一致
2740
- */
2741
- const PortalView = /* @__PURE__ */ vue.defineComponent({
2742
- name: COMPONENT_NAME$_,
2743
- props: props$P,
3097
+ /** @jsxImportSource vue */
3098
+
3099
+ const COMPONENT_NAME$10 = 'vcm-toast';
3100
+ const MToastView = /* @__PURE__ */ vue.defineComponent({
3101
+ name: COMPONENT_NAME$10,
3102
+ emits: ['close', 'portal-fulfilled'],
3103
+ props: props$Q,
2744
3104
  setup(props, {
2745
- slots
3105
+ emit,
3106
+ expose
2746
3107
  }) {
3108
+ const isActive = vue.ref(false);
3109
+ const currentContent = vue.ref();
3110
+ let timer;
3111
+ const setDuration = v => {
3112
+ timer && clearTimeout(timer);
3113
+ if (v === 0) return;
3114
+ timer = setTimeout(() => isActive.value = false, v);
3115
+ };
3116
+ const setContent = v => {
3117
+ currentContent.value = v;
3118
+ };
3119
+
3120
+ // 兼容Portal设计
3121
+ const handleRemove = () => {
3122
+ emit('close');
3123
+ emit('portal-fulfilled');
3124
+ };
3125
+ const handleClose = () => {
3126
+ if (props.maskClosable) {
3127
+ isActive.value = false;
3128
+ }
3129
+ };
3130
+ vue.watch(() => props.content, setContent, {
3131
+ immediate: true
3132
+ });
3133
+ vue.onMounted(() => {
3134
+ isActive.value = true;
3135
+ setDuration(props.duration);
3136
+ });
3137
+ vue.onUnmounted(() => {
3138
+ timer && clearTimeout(timer);
3139
+ });
3140
+ const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
3141
+ pre[key] = handleRemove;
3142
+ return pre;
3143
+ }, {
3144
+ setContent,
3145
+ setDuration
3146
+ });
3147
+ expose(exposes);
2747
3148
  return () => {
2748
- /**
2749
- * 考虑占位的情况下需要渲染default
2750
- */
2751
- return vue.h(vue.Fragment, [vue.h(props.tag, {
2752
- class: 'vc-portal-view'
2753
- }, slots?.default?.()), vue.h(vue.Teleport, {
2754
- to: 'body'
2755
- }, slots?.content?.())]);
3149
+ return vue.createVNode("div", {
3150
+ "class": "vcm-toast"
3151
+ }, [vue.createVNode("div", {
3152
+ "class": "vcm-toast__bg",
3153
+ "onClick": handleClose,
3154
+ "onTouchmove": vue.withModifiers(() => {}, ['prevent'])
3155
+ }, null), vue.createVNode(MTransitionFade, {
3156
+ "duration": {
3157
+ enter: 300,
3158
+ leave: 150
3159
+ },
3160
+ "onAfterLeave": handleRemove
3161
+ }, {
3162
+ default: () => [vue.withDirectives(vue.createVNode("div", {
3163
+ "class": "vcm-toast__wrapper"
3164
+ }, [props.mode === 'loading' && vue.createVNode(MSpin, {
3165
+ "class": "vcm-toast__loading"
3166
+ }, null), typeof currentContent.value === 'string' ? vue.createVNode("div", {
3167
+ "class": "vcm-toast__content",
3168
+ "innerHTML": currentContent.value
3169
+ }, null) : typeof currentContent.value === 'function' ? vue.createVNode(MCustomer, {
3170
+ "render": currentContent.value
3171
+ }, null) : null]), [[vue.vShow, isActive.value]])]
3172
+ })]);
2756
3173
  };
2757
3174
  }
2758
3175
  });
@@ -2792,9 +3209,9 @@ const MToast$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
2792
3209
  warning: warning$3
2793
3210
  }, Symbol.toStringTag, { value: 'Module' }));
2794
3211
 
2795
- const COMPONENT_NAME$Z = "vcm-form";
3212
+ const COMPONENT_NAME$$ = "vcm-form";
2796
3213
  const MForm = vue.defineComponent({
2797
- name: COMPONENT_NAME$Z,
3214
+ name: COMPONENT_NAME$$,
2798
3215
  props: props$R,
2799
3216
  setup(props, { slots, expose }) {
2800
3217
  useForm(expose, {
@@ -2815,7 +3232,7 @@ const MForm = vue.defineComponent({
2815
3232
  }
2816
3233
  });
2817
3234
 
2818
- const props$O = {
3235
+ const props$P = {
2819
3236
  ...props$S,
2820
3237
  indent: {
2821
3238
  type: Number,
@@ -2825,10 +3242,10 @@ const props$O = {
2825
3242
 
2826
3243
  /** @jsxImportSource vue */
2827
3244
 
2828
- const COMPONENT_NAME$Y = 'vcm-form-item';
3245
+ const COMPONENT_NAME$_ = 'vcm-form-item';
2829
3246
  const MFormItem = /* @__PURE__ */ vue.defineComponent({
2830
- name: COMPONENT_NAME$Y,
2831
- props: props$O,
3247
+ name: COMPONENT_NAME$_,
3248
+ props: props$P,
2832
3249
  setup(props, {
2833
3250
  slots,
2834
3251
  expose
@@ -2881,9 +3298,9 @@ const MFormItem = /* @__PURE__ */ vue.defineComponent({
2881
3298
  }
2882
3299
  });
2883
3300
 
2884
- const COMPONENT_NAME$X = "vc-fragment";
3301
+ const COMPONENT_NAME$Z = "vc-fragment";
2885
3302
  const Fragment = vue.defineComponent({
2886
- name: COMPONENT_NAME$X,
3303
+ name: COMPONENT_NAME$Z,
2887
3304
  setup(_, { slots }) {
2888
3305
  return () => vue.h(vue.Fragment, slots.default?.());
2889
3306
  }
@@ -2891,7 +3308,7 @@ const Fragment = vue.defineComponent({
2891
3308
 
2892
3309
  const MFragment = Fragment;
2893
3310
 
2894
- const props$N = {
3311
+ const props$O = {
2895
3312
  tag: {
2896
3313
  type: String,
2897
3314
  default: "div"
@@ -2900,10 +3317,10 @@ const props$N = {
2900
3317
 
2901
3318
  /** @jsxImportSource vue */
2902
3319
 
2903
- const COMPONENT_NAME$W = 'vc-html-to-image';
3320
+ const COMPONENT_NAME$Y = 'vc-html-to-image';
2904
3321
  const HTMLToImage = /* @__PURE__ */ vue.defineComponent({
2905
- name: COMPONENT_NAME$W,
2906
- props: props$N,
3322
+ name: COMPONENT_NAME$Y,
3323
+ props: props$O,
2907
3324
  setup(props, {
2908
3325
  slots
2909
3326
  }) {
@@ -2919,7 +3336,7 @@ const MHTMLToImage = HTMLToImage;
2919
3336
 
2920
3337
  const MIcon = Icon;
2921
3338
 
2922
- const props$M = {
3339
+ const props$N = {
2923
3340
  src: String,
2924
3341
  fit: String,
2925
3342
  lazy: Boolean,
@@ -2978,7 +3395,7 @@ const IMGStore$1 = new IMGStore();
2978
3395
 
2979
3396
  /** @jsxImportSource vue */
2980
3397
 
2981
- const COMPONENT_NAME$V = 'vc-image';
3398
+ const COMPONENT_NAME$X = 'vc-image';
2982
3399
  let isSupportObjectFit = false;
2983
3400
  window.addEventListener('DOMContentLoaded', () => {
2984
3401
  isSupportObjectFit = !vcShared.IS_SERVER && document.documentElement.style.objectFit !== undefined;
@@ -2991,9 +3408,9 @@ const ObjectFit = {
2991
3408
  SCALE_DOWN: 'scale-down'
2992
3409
  };
2993
3410
  const Image = /* @__PURE__ */ vue.defineComponent({
2994
- name: COMPONENT_NAME$V,
3411
+ name: COMPONENT_NAME$X,
2995
3412
  inheritAttrs: false,
2996
- props: props$M,
3413
+ props: props$N,
2997
3414
  setup(props, {
2998
3415
  slots,
2999
3416
  emit
@@ -3187,7 +3604,7 @@ const Image = /* @__PURE__ */ vue.defineComponent({
3187
3604
 
3188
3605
  const MImage = Image;
3189
3606
 
3190
- const props$L = {
3607
+ const props$M = {
3191
3608
  tag: {
3192
3609
  type: String,
3193
3610
  default: "div"
@@ -3196,10 +3613,10 @@ const props$L = {
3196
3613
 
3197
3614
  /** @jsxImportSource vue */
3198
3615
 
3199
- const COMPONENT_NAME$U = 'vc-image-crop';
3616
+ const COMPONENT_NAME$W = 'vc-image-crop';
3200
3617
  const ImageCrop = /* @__PURE__ */ vue.defineComponent({
3201
- name: COMPONENT_NAME$U,
3202
- props: props$L,
3618
+ name: COMPONENT_NAME$W,
3619
+ props: props$M,
3203
3620
  setup(props, {
3204
3621
  slots
3205
3622
  }) {
@@ -3213,7 +3630,7 @@ const ImageCrop = /* @__PURE__ */ vue.defineComponent({
3213
3630
 
3214
3631
  const MImageCrop = ImageCrop;
3215
3632
 
3216
- const props$K = {
3633
+ const props$L = {
3217
3634
  tag: {
3218
3635
  type: String,
3219
3636
  default: "div"
@@ -3222,10 +3639,10 @@ const props$K = {
3222
3639
 
3223
3640
  /** @jsxImportSource vue */
3224
3641
 
3225
- const COMPONENT_NAME$T = 'vc-image-preview';
3642
+ const COMPONENT_NAME$V = 'vc-image-preview';
3226
3643
  const ImagePreview = /* @__PURE__ */ vue.defineComponent({
3227
- name: COMPONENT_NAME$T,
3228
- props: props$K,
3644
+ name: COMPONENT_NAME$V,
3645
+ props: props$L,
3229
3646
  setup(props, {
3230
3647
  slots
3231
3648
  }) {
@@ -3239,7 +3656,7 @@ const ImagePreview = /* @__PURE__ */ vue.defineComponent({
3239
3656
 
3240
3657
  const MImagePreview = ImagePreview;
3241
3658
 
3242
- const props$J = {
3659
+ const props$K = {
3243
3660
  tag: {
3244
3661
  type: String,
3245
3662
  default: "div"
@@ -3248,10 +3665,10 @@ const props$J = {
3248
3665
 
3249
3666
  /** @jsxImportSource vue */
3250
3667
 
3251
- const COMPONENT_NAME$S = 'vc-image-processing';
3668
+ const COMPONENT_NAME$U = 'vc-image-processing';
3252
3669
  const ImageProcessing = /* @__PURE__ */ vue.defineComponent({
3253
- name: COMPONENT_NAME$S,
3254
- props: props$J,
3670
+ name: COMPONENT_NAME$U,
3671
+ props: props$K,
3255
3672
  setup(props, {
3256
3673
  slots
3257
3674
  }) {
@@ -3265,7 +3682,7 @@ const ImageProcessing = /* @__PURE__ */ vue.defineComponent({
3265
3682
 
3266
3683
  const MImageProcessing = ImageProcessing;
3267
3684
 
3268
- const props$I = {
3685
+ const props$J = {
3269
3686
  // Array, 作为select等数组存放临时值
3270
3687
  modelValue: {
3271
3688
  type: [String, Number, Array],
@@ -3364,7 +3781,7 @@ const useInput = (input) => {
3364
3781
  const isFocus = vue.ref(false);
3365
3782
  const isClearing = vue.ref(false);
3366
3783
  const isOnComposition = vue.ref(false);
3367
- const formItem = vue.inject("form-item", {});
3784
+ const formItem = vue.inject("vc-form-item", {});
3368
3785
  vue.watch(
3369
3786
  () => props.modelValue,
3370
3787
  (v) => {
@@ -3519,12 +3936,12 @@ const useNativeEmitter = (input, expose) => {
3519
3936
 
3520
3937
  /** @jsxImportSource vue */
3521
3938
 
3522
- const COMPONENT_NAME$R = 'vc-input';
3939
+ const COMPONENT_NAME$T = 'vc-input';
3523
3940
  const Input = /* @__PURE__ */ vue.defineComponent({
3524
- name: COMPONENT_NAME$R,
3941
+ name: COMPONENT_NAME$T,
3525
3942
  inheritAttrs: false,
3526
3943
  props: {
3527
- ...props$I,
3944
+ ...props$J,
3528
3945
  indicator: {
3529
3946
  type: [Boolean, Object],
3530
3947
  default: false
@@ -3625,8 +4042,8 @@ const Input = /* @__PURE__ */ vue.defineComponent({
3625
4042
  }
3626
4043
  });
3627
4044
 
3628
- const props$H = {
3629
- ...props$I,
4045
+ const props$I = {
4046
+ ...props$J,
3630
4047
  min: {
3631
4048
  type: Number,
3632
4049
  default: 0
@@ -3841,10 +4258,10 @@ const useInputNumber = () => {
3841
4258
 
3842
4259
  /** @jsxImportSource vue */
3843
4260
 
3844
- const COMPONENT_NAME$Q = 'vc-input-number';
4261
+ const COMPONENT_NAME$S = 'vc-input-number';
3845
4262
  const InputNumber = /* @__PURE__ */ vue.defineComponent({
3846
- name: COMPONENT_NAME$Q,
3847
- props: props$H,
4263
+ name: COMPONENT_NAME$S,
4264
+ props: props$I,
3848
4265
  inheritAttrs: false,
3849
4266
  setup(props, {
3850
4267
  slots,
@@ -3895,8 +4312,8 @@ const InputNumber = /* @__PURE__ */ vue.defineComponent({
3895
4312
  }
3896
4313
  });
3897
4314
 
3898
- const props$G = {
3899
- ...props$I,
4315
+ const props$H = {
4316
+ ...props$J,
3900
4317
  enterText: {
3901
4318
  type: [Boolean, String],
3902
4319
  default: true
@@ -3905,10 +4322,10 @@ const props$G = {
3905
4322
 
3906
4323
  /** @jsxImportSource vue */
3907
4324
 
3908
- const COMPONENT_NAME$P = 'vc-input-search';
4325
+ const COMPONENT_NAME$R = 'vc-input-search';
3909
4326
  const InputSearch = /* @__PURE__ */ vue.defineComponent({
3910
- name: COMPONENT_NAME$P,
3911
- props: props$G,
4327
+ name: COMPONENT_NAME$R,
4328
+ props: props$H,
3912
4329
  inheritAttrs: false,
3913
4330
  setup(props, {
3914
4331
  emit,
@@ -3942,12 +4359,12 @@ const InputSearch = /* @__PURE__ */ vue.defineComponent({
3942
4359
 
3943
4360
  /** @jsxImportSource vue */
3944
4361
 
3945
- const COMPONENT_NAME$O = 'vcm-input';
4362
+ const COMPONENT_NAME$Q = 'vcm-input';
3946
4363
  const MInput = /* @__PURE__ */ vue.defineComponent({
3947
- name: COMPONENT_NAME$O,
4364
+ name: COMPONENT_NAME$Q,
3948
4365
  inheritAttrs: false,
3949
4366
  props: {
3950
- ...props$I,
4367
+ ...props$J,
3951
4368
  right: {
3952
4369
  type: Boolean,
3953
4370
  default: false
@@ -4033,10 +4450,10 @@ const MInput = /* @__PURE__ */ vue.defineComponent({
4033
4450
 
4034
4451
  /** @jsxImportSource vue */
4035
4452
 
4036
- const COMPONENT_NAME$N = 'vcm-input-number';
4453
+ const COMPONENT_NAME$P = 'vcm-input-number';
4037
4454
  const MInputNumber = /* @__PURE__ */ vue.defineComponent({
4038
- name: COMPONENT_NAME$N,
4039
- props: props$H,
4455
+ name: COMPONENT_NAME$P,
4456
+ props: props$I,
4040
4457
  inheritAttrs: false,
4041
4458
  setup(props, {
4042
4459
  slots,
@@ -4084,11 +4501,11 @@ const MInputNumber = /* @__PURE__ */ vue.defineComponent({
4084
4501
 
4085
4502
  /** @jsxImportSource vue */
4086
4503
 
4087
- const COMPONENT_NAME$M = 'vcm-input-search';
4504
+ const COMPONENT_NAME$O = 'vcm-input-search';
4088
4505
  const MInputSearch = /* @__PURE__ */ vue.defineComponent({
4089
- name: COMPONENT_NAME$M,
4506
+ name: COMPONENT_NAME$O,
4090
4507
  props: {
4091
- ...props$G,
4508
+ ...props$H,
4092
4509
  cancelText: {
4093
4510
  type: String,
4094
4511
  default: '取消'
@@ -4148,7 +4565,7 @@ const MInputSearch = /* @__PURE__ */ vue.defineComponent({
4148
4565
  }
4149
4566
  });
4150
4567
 
4151
- const props$F = {
4568
+ const props$G = {
4152
4569
  tag: {
4153
4570
  type: String,
4154
4571
  default: "div"
@@ -4163,12 +4580,12 @@ const props$F = {
4163
4580
  }
4164
4581
  };
4165
4582
 
4166
- const COMPONENT_NAME$L = "vcm-list";
4583
+ const COMPONENT_NAME$N = "vcm-list";
4167
4584
  const MList = vue.defineComponent({
4168
- name: COMPONENT_NAME$L,
4169
- props: props$F,
4585
+ name: COMPONENT_NAME$N,
4586
+ props: props$G,
4170
4587
  setup(props, { slots }) {
4171
- vue.provide("list", { props });
4588
+ vue.provide("vc-list", { props });
4172
4589
  return () => {
4173
4590
  return vue.h(
4174
4591
  props.tag,
@@ -4186,7 +4603,7 @@ const MList = vue.defineComponent({
4186
4603
  }
4187
4604
  });
4188
4605
 
4189
- const props$E = {
4606
+ const props$F = {
4190
4607
  tag: {
4191
4608
  type: String,
4192
4609
  default: "div"
@@ -4220,17 +4637,17 @@ const props$E = {
4220
4637
 
4221
4638
  /** @jsxImportSource vue */
4222
4639
 
4223
- const COMPONENT_NAME$K = 'vcm-list-item';
4640
+ const COMPONENT_NAME$M = 'vcm-list-item';
4224
4641
  const HTTP_REGEX = /[a-zA-z]+:\/\/[^\s]*/;
4225
4642
  const MListItem = /* @__PURE__ */ vue.defineComponent({
4226
- name: COMPONENT_NAME$K,
4227
- props: props$E,
4643
+ name: COMPONENT_NAME$M,
4644
+ props: props$F,
4228
4645
  emits: ['click'],
4229
4646
  setup(props, {
4230
4647
  slots,
4231
4648
  emit
4232
4649
  }) {
4233
- const list = vue.inject('list', {});
4650
+ const list = vue.inject('vc-list', {});
4234
4651
  const classes = vue.computed(() => {
4235
4652
  const hasList = !!list.props;
4236
4653
  return {
@@ -4298,7 +4715,7 @@ const MListItem = /* @__PURE__ */ vue.defineComponent({
4298
4715
  }
4299
4716
  });
4300
4717
 
4301
- const props$D = {
4718
+ const props$E = {
4302
4719
  tag: {
4303
4720
  type: String,
4304
4721
  default: "div"
@@ -4307,10 +4724,10 @@ const props$D = {
4307
4724
 
4308
4725
  /** @jsxImportSource vue */
4309
4726
 
4310
- const COMPONENT_NAME$J = 'vc-marquee';
4727
+ const COMPONENT_NAME$L = 'vc-marquee';
4311
4728
  const Marquee = /* @__PURE__ */ vue.defineComponent({
4312
- name: COMPONENT_NAME$J,
4313
- props: props$D,
4729
+ name: COMPONENT_NAME$L,
4730
+ props: props$E,
4314
4731
  setup(props, {
4315
4732
  slots
4316
4733
  }) {
@@ -4324,7 +4741,7 @@ const Marquee = /* @__PURE__ */ vue.defineComponent({
4324
4741
 
4325
4742
  const MMarquee = Marquee;
4326
4743
 
4327
- const props$C = {
4744
+ const props$D = {
4328
4745
  content: [String, Function],
4329
4746
  mask: {
4330
4747
  type: Boolean,
@@ -4338,6 +4755,7 @@ const props$C = {
4338
4755
  type: Boolean,
4339
4756
  default: true
4340
4757
  },
4758
+ // 单位ms
4341
4759
  duration: {
4342
4760
  type: Number,
4343
4761
  default: 1500
@@ -4361,17 +4779,27 @@ const props$C = {
4361
4779
 
4362
4780
  /** @jsxImportSource vue */
4363
4781
 
4364
- const COMPONENT_NAME$I = 'vc-message';
4782
+ const COMPONENT_NAME$K = 'vc-message';
4365
4783
  const MessageView = /* @__PURE__ */ vue.defineComponent({
4366
- name: COMPONENT_NAME$I,
4784
+ name: COMPONENT_NAME$K,
4367
4785
  emits: ['before-close', 'close', 'portal-fulfilled'],
4368
- props: props$C,
4786
+ props: props$D,
4369
4787
  setup(props, {
4370
4788
  emit,
4371
4789
  expose
4372
4790
  }) {
4373
4791
  const instance = vue.getCurrentInstance();
4374
4792
  const isActive = vue.ref(false);
4793
+ const currentContent = vue.ref();
4794
+ let timer;
4795
+ const setDuration = v => {
4796
+ timer && clearTimeout(timer);
4797
+ if (v === 0) return;
4798
+ timer = setTimeout(() => isActive.value = false, v);
4799
+ };
4800
+ const setContent = v => {
4801
+ currentContent.value = v;
4802
+ };
4375
4803
 
4376
4804
  // 兼容Portal设计
4377
4805
  const handleRemove = () => {
@@ -4391,15 +4819,12 @@ const MessageView = /* @__PURE__ */ vue.defineComponent({
4391
4819
  isActive.value = false;
4392
4820
  }
4393
4821
  };
4394
- let timer;
4822
+ vue.watch(() => props.content, setContent, {
4823
+ immediate: true
4824
+ });
4395
4825
  vue.onMounted(() => {
4396
4826
  isActive.value = true;
4397
- if (props.duration !== 0) {
4398
- timer = setTimeout(() => {
4399
- // 主线程
4400
- isActive.value = false;
4401
- }, props.duration * 1000 - 300); // 动画时间
4402
- }
4827
+ setDuration(props.duration);
4403
4828
  });
4404
4829
  vue.onUnmounted(() => {
4405
4830
  timer && clearTimeout(timer);
@@ -4407,7 +4832,10 @@ const MessageView = /* @__PURE__ */ vue.defineComponent({
4407
4832
  const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
4408
4833
  pre[key] = handleRemove;
4409
4834
  return pre;
4410
- }, {});
4835
+ }, {
4836
+ setContent,
4837
+ setDuration
4838
+ });
4411
4839
  expose(exposes);
4412
4840
  return () => {
4413
4841
  return vue.createVNode("div", {
@@ -4416,7 +4844,7 @@ const MessageView = /* @__PURE__ */ vue.defineComponent({
4416
4844
  "class": "vc-message__mask",
4417
4845
  "onClick": e => handleClose(e, props.maskClosable)
4418
4846
  }, null), vue.createVNode(TransitionSlide, {
4419
- "mode": "up",
4847
+ "mode": "bottom",
4420
4848
  "onAfterLeave": handleRemove
4421
4849
  }, {
4422
4850
  default: () => [vue.withDirectives(vue.createVNode("div", {
@@ -4434,11 +4862,11 @@ const MessageView = /* @__PURE__ */ vue.defineComponent({
4434
4862
  }, null) : vue.createVNode(Icon, {
4435
4863
  "type": props.mode,
4436
4864
  "class": [`is-${props.mode}`, 'vc-message__icon']
4437
- }, null), typeof props.content === 'string' ? vue.createVNode("div", {
4865
+ }, null), typeof currentContent.value === 'string' ? vue.createVNode("div", {
4438
4866
  "class": "vc-message__content",
4439
- "innerHTML": props.content
4440
- }, null) : typeof props.content === 'function' ? vue.createVNode(Customer, {
4441
- "render": props.content
4867
+ "innerHTML": currentContent.value
4868
+ }, null) : typeof currentContent.value === 'function' ? vue.createVNode(Customer, {
4869
+ "render": currentContent.value
4442
4870
  }, null) : null, props.closable && vue.createVNode(Icon, {
4443
4871
  "type": "close",
4444
4872
  "class": "vc-message__close",
@@ -4496,7 +4924,7 @@ const Message$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty(
4496
4924
 
4497
4925
  const MMessage = Message$1;
4498
4926
 
4499
- const props$B = {
4927
+ const props$C = {
4500
4928
  modelValue: {
4501
4929
  type: Boolean,
4502
4930
  default: false
@@ -4576,12 +5004,12 @@ const props$B = {
4576
5004
 
4577
5005
  /** @jsxImportSource vue */
4578
5006
 
4579
- const COMPONENT_NAME$H = 'vc-modal';
5007
+ const COMPONENT_NAME$J = 'vc-modal';
4580
5008
  let zIndexNumber = 1002;
4581
5009
  const ModalView = /* @__PURE__ */ vue.defineComponent({
4582
- name: COMPONENT_NAME$H,
5010
+ name: COMPONENT_NAME$J,
4583
5011
  emits: ['update:modelValue', 'close', 'portal-fulfilled', 'visible-change', 'ok', 'cancel'],
4584
- props: props$B,
5012
+ props: props$C,
4585
5013
  setup(props, {
4586
5014
  slots,
4587
5015
  emit,
@@ -4808,6 +5236,10 @@ const ModalView = /* @__PURE__ */ vue.defineComponent({
4808
5236
  expose({
4809
5237
  isActive,
4810
5238
  // for portal
5239
+ toggle(v) {
5240
+ v = typeof v === 'boolean' ? v : !isActive.value;
5241
+ isActive.value = v;
5242
+ },
4811
5243
  resetOrigin
4812
5244
  });
4813
5245
  return () => {
@@ -4898,7 +5330,7 @@ const create$2 = (mode) => (options) => {
4898
5330
  // 当组件内使用emit('close'),避免重复触发
4899
5331
  onClose: null
4900
5332
  });
4901
- leaf.wrapper.isActive = true;
5333
+ leaf.wrapper.toggle?.(true);
4902
5334
  return leaf;
4903
5335
  };
4904
5336
  const destroy$2 = () => Modal.destroy();
@@ -4916,7 +5348,7 @@ const modal$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
4916
5348
  warning: warning$1
4917
5349
  }, Symbol.toStringTag, { value: 'Module' }));
4918
5350
 
4919
- const props$A = {
5351
+ const props$B = {
4920
5352
  mode: {
4921
5353
  type: String,
4922
5354
  validator: (v) => /(alert|operation)/.test(v),
@@ -4978,11 +5410,11 @@ const props$A = {
4978
5410
 
4979
5411
  /** @jsxImportSource vue */
4980
5412
 
4981
- const COMPONENT_NAME$G = 'vc-modal';
5413
+ const COMPONENT_NAME$I = 'vc-modal';
4982
5414
  const MModalView = /* @__PURE__ */ vue.defineComponent({
4983
- name: COMPONENT_NAME$G,
5415
+ name: COMPONENT_NAME$I,
4984
5416
  emits: ['update:modelValue', 'portal-fulfilled', 'close', 'ok', 'cancel'],
4985
- props: props$A,
5417
+ props: props$B,
4986
5418
  setup(props, {
4987
5419
  slots,
4988
5420
  emit,
@@ -5155,12 +5587,13 @@ const modal = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5155
5587
  operation
5156
5588
  }, Symbol.toStringTag, { value: 'Module' }));
5157
5589
 
5158
- const props$z = {
5590
+ const props$A = {
5159
5591
  title: [String, Function],
5160
5592
  content: [String, Function],
5593
+ // 单位ms
5161
5594
  duration: {
5162
5595
  type: Number,
5163
- default: 450
5596
+ default: 4500
5164
5597
  },
5165
5598
  closable: {
5166
5599
  type: Boolean,
@@ -5184,29 +5617,31 @@ const props$z = {
5184
5617
 
5185
5618
  /** @jsxImportSource vue */
5186
5619
 
5187
- const COMPONENT_NAME$F = 'vc-notice';
5620
+ const COMPONENT_NAME$H = 'vc-notice';
5188
5621
  const NoticeView = /* @__PURE__ */ vue.defineComponent({
5189
- name: COMPONENT_NAME$F,
5190
- props: props$z,
5622
+ name: COMPONENT_NAME$H,
5623
+ props: props$A,
5191
5624
  emits: ['portal-fulfilled', 'close', 'before-close'],
5192
5625
  setup(props, {
5193
- emit
5626
+ emit,
5627
+ expose
5194
5628
  }) {
5195
5629
  const instance = vue.getCurrentInstance();
5196
5630
  const isActive = vue.ref(false);
5631
+ const currentTitle = vue.ref();
5632
+ const currentContent = vue.ref();
5197
5633
  let timer;
5198
- vue.onMounted(() => {
5199
- isActive.value = true;
5200
- if (props.duration !== 0) {
5201
- timer = setTimeout(() => {
5202
- // 主线程
5203
- isActive.value = false;
5204
- }, props.duration * 1000 - 300); // 动画时间
5205
- }
5206
- });
5207
- vue.onUnmounted(() => {
5634
+ const setDuration = v => {
5208
5635
  timer && clearTimeout(timer);
5209
- });
5636
+ if (v === 0) return;
5637
+ timer = setTimeout(() => isActive.value = false, v);
5638
+ };
5639
+ const setTitle = v => {
5640
+ currentTitle.value = v;
5641
+ };
5642
+ const setContent = v => {
5643
+ currentContent.value = v;
5644
+ };
5210
5645
 
5211
5646
  // 兼容Portal设计
5212
5647
  const handleRemove = () => {
@@ -5226,6 +5661,27 @@ const NoticeView = /* @__PURE__ */ vue.defineComponent({
5226
5661
  isActive.value = false;
5227
5662
  }
5228
5663
  };
5664
+ vue.watch(() => props.title, setTitle, {
5665
+ immediate: true
5666
+ });
5667
+ vue.watch(() => props.content, setContent, {
5668
+ immediate: true
5669
+ });
5670
+ vue.onMounted(() => {
5671
+ isActive.value = true;
5672
+ setDuration(props.duration);
5673
+ });
5674
+ vue.onUnmounted(() => {
5675
+ timer && clearTimeout(timer);
5676
+ });
5677
+ const exposes = ['destroy', 'remove', 'close', 'hide'].reduce((pre, key) => {
5678
+ pre[key] = handleRemove;
5679
+ return pre;
5680
+ }, {
5681
+ setContent,
5682
+ setDuration
5683
+ });
5684
+ expose(exposes);
5229
5685
  return () => {
5230
5686
  return vue.createVNode("div", {
5231
5687
  "class": ['vc-notice', {
@@ -5245,21 +5701,21 @@ const NoticeView = /* @__PURE__ */ vue.defineComponent({
5245
5701
  }, [props.mode && vue.createVNode(Icon, {
5246
5702
  "type": `o-${props.mode}`,
5247
5703
  "class": [`is-${props.mode}`, 'vc-notice__icon']
5248
- }, null), vue.createVNode("div", null, [props.title && vue.createVNode("div", {
5704
+ }, null), vue.createVNode("div", null, [currentTitle.value && vue.createVNode("div", {
5249
5705
  "style": [{
5250
- marginBottom: props.content ? '8px' : ''
5706
+ marginBottom: currentContent.value ? '8px' : ''
5251
5707
  }],
5252
5708
  "class": "vc-notice__title"
5253
- }, [typeof props.title === 'string' ? vue.createVNode("div", {
5254
- "innerHTML": props.title
5255
- }, null) : typeof props.title === 'function' ? vue.createVNode(Customer, {
5256
- "render": props.title
5257
- }, null) : null]), props.content && vue.createVNode("div", {
5709
+ }, [typeof currentTitle.value === 'string' ? vue.createVNode("div", {
5710
+ "innerHTML": currentTitle.value
5711
+ }, null) : typeof currentTitle.value === 'function' ? vue.createVNode(Customer, {
5712
+ "render": currentTitle.value
5713
+ }, null) : null]), currentContent.value && vue.createVNode("div", {
5258
5714
  "class": "vc-notice__content"
5259
- }, [typeof props.content === 'string' ? vue.createVNode("div", {
5260
- "innerHTML": props.content
5261
- }, null) : typeof props.content === 'function' ? vue.createVNode(Customer, {
5262
- "render": props.content
5715
+ }, [typeof currentContent.value === 'string' ? vue.createVNode("div", {
5716
+ "innerHTML": currentContent.value
5717
+ }, null) : typeof currentContent.value === 'function' ? vue.createVNode(Customer, {
5718
+ "render": currentContent.value
5263
5719
  }, null) : null])]), props.closable && vue.createVNode(Icon, {
5264
5720
  "type": "close",
5265
5721
  "style": "font-size: 12px",
@@ -5336,7 +5792,7 @@ const Notice$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
5336
5792
 
5337
5793
  const MNotice = Notice$1;
5338
5794
 
5339
- const props$y = {
5795
+ const props$z = {
5340
5796
  tag: {
5341
5797
  type: String,
5342
5798
  default: "div"
@@ -5345,10 +5801,10 @@ const props$y = {
5345
5801
 
5346
5802
  /** @jsxImportSource vue */
5347
5803
 
5348
- const COMPONENT_NAME$E = 'vc-option';
5804
+ const COMPONENT_NAME$G = 'vc-option';
5349
5805
  const Option = /* @__PURE__ */ vue.defineComponent({
5350
- name: COMPONENT_NAME$E,
5351
- props: props$y,
5806
+ name: COMPONENT_NAME$G,
5807
+ props: props$z,
5352
5808
  setup(props, {
5353
5809
  slots
5354
5810
  }) {
@@ -5362,7 +5818,7 @@ const Option = /* @__PURE__ */ vue.defineComponent({
5362
5818
 
5363
5819
  const MOption = Option;
5364
5820
 
5365
- const props$x = {
5821
+ const props$y = {
5366
5822
  tag: {
5367
5823
  type: String,
5368
5824
  default: "div"
@@ -5371,10 +5827,10 @@ const props$x = {
5371
5827
 
5372
5828
  /** @jsxImportSource vue */
5373
5829
 
5374
- const COMPONENT_NAME$D = 'vc-page';
5830
+ const COMPONENT_NAME$F = 'vc-page';
5375
5831
  const Page = /* @__PURE__ */ vue.defineComponent({
5376
- name: COMPONENT_NAME$D,
5377
- props: props$x,
5832
+ name: COMPONENT_NAME$F,
5833
+ props: props$y,
5378
5834
  setup(props, {
5379
5835
  slots
5380
5836
  }) {
@@ -5388,7 +5844,7 @@ const Page = /* @__PURE__ */ vue.defineComponent({
5388
5844
 
5389
5845
  const MPage = Page;
5390
5846
 
5391
- const props$w = {
5847
+ const props$x = {
5392
5848
  tag: {
5393
5849
  type: String,
5394
5850
  default: "div"
@@ -5397,10 +5853,10 @@ const props$w = {
5397
5853
 
5398
5854
  /** @jsxImportSource vue */
5399
5855
 
5400
- const COMPONENT_NAME$C = 'vc-picker';
5856
+ const COMPONENT_NAME$E = 'vc-picker';
5401
5857
  const Picker = /* @__PURE__ */ vue.defineComponent({
5402
- name: COMPONENT_NAME$C,
5403
- props: props$w,
5858
+ name: COMPONENT_NAME$E,
5859
+ props: props$x,
5404
5860
  setup(props, {
5405
5861
  slots
5406
5862
  }) {
@@ -5414,7 +5870,7 @@ const Picker = /* @__PURE__ */ vue.defineComponent({
5414
5870
 
5415
5871
  const MPicker = Picker;
5416
5872
 
5417
- const props$v = {
5873
+ const props$w = {
5418
5874
  tag: {
5419
5875
  type: String,
5420
5876
  default: "div"
@@ -5423,10 +5879,10 @@ const props$v = {
5423
5879
 
5424
5880
  /** @jsxImportSource vue */
5425
5881
 
5426
- const COMPONENT_NAME$B = 'vc-popconfirm';
5882
+ const COMPONENT_NAME$D = 'vc-popconfirm';
5427
5883
  const Popconfirm = /* @__PURE__ */ vue.defineComponent({
5428
- name: COMPONENT_NAME$B,
5429
- props: props$v,
5884
+ name: COMPONENT_NAME$D,
5885
+ props: props$w,
5430
5886
  setup(props, {
5431
5887
  slots
5432
5888
  }) {
@@ -5440,7 +5896,7 @@ const Popconfirm = /* @__PURE__ */ vue.defineComponent({
5440
5896
 
5441
5897
  const MPopconfirm = Popconfirm;
5442
5898
 
5443
- const props$u = {
5899
+ const props$v = {
5444
5900
  modelValue: Boolean,
5445
5901
  animation: String,
5446
5902
  placement: {
@@ -5519,7 +5975,7 @@ const wrapperKeys = [
5519
5975
  "autoWidth",
5520
5976
  "always"
5521
5977
  ];
5522
- const props$t = {
5978
+ const props$u = {
5523
5979
  trigger: {
5524
5980
  type: String,
5525
5981
  default: "hover",
@@ -5537,7 +5993,7 @@ const props$t = {
5537
5993
  type: Boolean,
5538
5994
  default: true
5539
5995
  },
5540
- ...lodashEs.pick(props$u, wrapperKeys)
5996
+ ...lodashEs.pick(props$v, wrapperKeys)
5541
5997
  };
5542
5998
 
5543
5999
  const EXTRA_DISTANCE = 4;
@@ -5798,10 +6254,10 @@ const usePos = () => {
5798
6254
  function _isSlot(s) {
5799
6255
  return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s);
5800
6256
  }
5801
- const COMPONENT_NAME$A = 'vc-popover-wrapper';
6257
+ const COMPONENT_NAME$C = 'vc-popover-wrapper';
5802
6258
  const PopoverWrapper = /* @__PURE__ */ vue.defineComponent({
5803
- name: COMPONENT_NAME$A,
5804
- props: props$u,
6259
+ name: COMPONENT_NAME$C,
6260
+ props: props$v,
5805
6261
  emits: ['portal-fulfilled', 'close'],
5806
6262
  setup(props, {
5807
6263
  emit,
@@ -6011,7 +6467,11 @@ const PopoverWrapper = /* @__PURE__ */ vue.defineComponent({
6011
6467
  props.alone && props.hover && removeEvents();
6012
6468
  });
6013
6469
  expose({
6014
- isActive
6470
+ isActive,
6471
+ toggle(v) {
6472
+ v = typeof v === 'boolean' ? v : !isActive.value;
6473
+ isActive.value = v;
6474
+ }
6015
6475
  });
6016
6476
  return () => {
6017
6477
  let _slot;
@@ -6051,10 +6511,10 @@ const PopoverPortal = new Portal(PopoverWrapper);
6051
6511
 
6052
6512
  /** @jsxImportSource vue */
6053
6513
 
6054
- const COMPONENT_NAME$z = 'vc-popover';
6514
+ const COMPONENT_NAME$B = 'vc-popover';
6055
6515
  const Popover = /* @__PURE__ */ vue.defineComponent({
6056
- name: COMPONENT_NAME$z,
6057
- props: props$t,
6516
+ name: COMPONENT_NAME$B,
6517
+ props: props$u,
6058
6518
  emits: ['update:modelValue', 'visible-change', 'ready', 'close'],
6059
6519
  open: PopoverPortal.popup.bind(PopoverPortal),
6060
6520
  setup(props, {
@@ -6148,7 +6608,7 @@ const Popover = /* @__PURE__ */ vue.defineComponent({
6148
6608
  portalClass
6149
6609
  });
6150
6610
  } else if (popperInstance && popperInstance.wrapper) {
6151
- popperInstance.wrapper.isActive = false;
6611
+ popperInstance.wrapper.toggle(false);
6152
6612
  }
6153
6613
  };
6154
6614
  vue.watch(() => props.modelValue, v => {
@@ -6191,7 +6651,7 @@ const Popover = /* @__PURE__ */ vue.defineComponent({
6191
6651
 
6192
6652
  const MPopover = Popover;
6193
6653
 
6194
- const props$s = {
6654
+ const props$t = {
6195
6655
  tag: {
6196
6656
  type: String,
6197
6657
  default: "div"
@@ -6200,10 +6660,10 @@ const props$s = {
6200
6660
 
6201
6661
  /** @jsxImportSource vue */
6202
6662
 
6203
- const COMPONENT_NAME$y = 'vc-popup';
6663
+ const COMPONENT_NAME$A = 'vc-popup';
6204
6664
  const Popup = /* @__PURE__ */ vue.defineComponent({
6205
- name: COMPONENT_NAME$y,
6206
- props: props$s,
6665
+ name: COMPONENT_NAME$A,
6666
+ props: props$t,
6207
6667
  setup(props, {
6208
6668
  slots
6209
6669
  }) {
@@ -6219,7 +6679,7 @@ const MPopup = Popup;
6219
6679
 
6220
6680
  const MPortal = Portal;
6221
6681
 
6222
- const props$r = {
6682
+ const props$s = {
6223
6683
  tag: {
6224
6684
  type: String,
6225
6685
  default: "div"
@@ -6228,10 +6688,10 @@ const props$r = {
6228
6688
 
6229
6689
  /** @jsxImportSource vue */
6230
6690
 
6231
- const COMPONENT_NAME$x = 'vc-print';
6691
+ const COMPONENT_NAME$z = 'vc-print';
6232
6692
  const Print = /* @__PURE__ */ vue.defineComponent({
6233
- name: COMPONENT_NAME$x,
6234
- props: props$r,
6693
+ name: COMPONENT_NAME$z,
6694
+ props: props$s,
6235
6695
  setup(props, {
6236
6696
  slots
6237
6697
  }) {
@@ -6245,7 +6705,7 @@ const Print = /* @__PURE__ */ vue.defineComponent({
6245
6705
 
6246
6706
  const MPrint = Print;
6247
6707
 
6248
- const props$q = {
6708
+ const props$r = {
6249
6709
  tag: {
6250
6710
  type: String,
6251
6711
  default: "div"
@@ -6254,10 +6714,10 @@ const props$q = {
6254
6714
 
6255
6715
  /** @jsxImportSource vue */
6256
6716
 
6257
- const COMPONENT_NAME$w = 'vc-progress';
6717
+ const COMPONENT_NAME$y = 'vc-progress';
6258
6718
  const Progress = /* @__PURE__ */ vue.defineComponent({
6259
- name: COMPONENT_NAME$w,
6260
- props: props$q,
6719
+ name: COMPONENT_NAME$y,
6720
+ props: props$r,
6261
6721
  setup(props, {
6262
6722
  slots
6263
6723
  }) {
@@ -6271,7 +6731,7 @@ const Progress = /* @__PURE__ */ vue.defineComponent({
6271
6731
 
6272
6732
  const MProgress = Progress;
6273
6733
 
6274
- const props$p = {
6734
+ const props$q = {
6275
6735
  tag: {
6276
6736
  type: String,
6277
6737
  default: "div"
@@ -6280,10 +6740,10 @@ const props$p = {
6280
6740
 
6281
6741
  /** @jsxImportSource vue */
6282
6742
 
6283
- const COMPONENT_NAME$v = 'vc-radio';
6743
+ const COMPONENT_NAME$x = 'vc-radio';
6284
6744
  const Radio = /* @__PURE__ */ vue.defineComponent({
6285
- name: COMPONENT_NAME$v,
6286
- props: props$p,
6745
+ name: COMPONENT_NAME$x,
6746
+ props: props$q,
6287
6747
  setup(props, {
6288
6748
  slots
6289
6749
  }) {
@@ -6297,7 +6757,7 @@ const Radio = /* @__PURE__ */ vue.defineComponent({
6297
6757
 
6298
6758
  const MRadio = Radio;
6299
6759
 
6300
- const props$o = {
6760
+ const props$p = {
6301
6761
  tag: {
6302
6762
  type: String,
6303
6763
  default: "div"
@@ -6306,10 +6766,10 @@ const props$o = {
6306
6766
 
6307
6767
  /** @jsxImportSource vue */
6308
6768
 
6309
- const COMPONENT_NAME$u = 'vc-rate';
6769
+ const COMPONENT_NAME$w = 'vc-rate';
6310
6770
  const Rate = /* @__PURE__ */ vue.defineComponent({
6311
- name: COMPONENT_NAME$u,
6312
- props: props$o,
6771
+ name: COMPONENT_NAME$w,
6772
+ props: props$p,
6313
6773
  setup(props, {
6314
6774
  slots
6315
6775
  }) {
@@ -6323,7 +6783,7 @@ const Rate = /* @__PURE__ */ vue.defineComponent({
6323
6783
 
6324
6784
  const MRate = Rate;
6325
6785
 
6326
- const props$n = {
6786
+ const props$o = {
6327
6787
  data: {
6328
6788
  type: Array,
6329
6789
  default: () => []
@@ -6374,7 +6834,7 @@ const props$n = {
6374
6834
  renderRefresh: Function
6375
6835
  };
6376
6836
 
6377
- const props$m = {
6837
+ const props$n = {
6378
6838
  vertical: Boolean,
6379
6839
  wrapperSize: {
6380
6840
  type: Number,
@@ -6429,7 +6889,7 @@ const barKeys$1 = [
6429
6889
  "thumbStyle",
6430
6890
  "thumbClass"
6431
6891
  ];
6432
- const props$l = {
6892
+ const props$m = {
6433
6893
  // 如果存在滚动条宽度为false, 不存在则为true
6434
6894
  // 为false的情况下才能使用track-offset
6435
6895
  native: {
@@ -6460,7 +6920,7 @@ const props$l = {
6460
6920
  scrollX: Number,
6461
6921
  scrollY: Number,
6462
6922
  fit: Boolean,
6463
- ...lodashEs.pick(props$m, barKeys$1)
6923
+ ...lodashEs.pick(props$n, barKeys$1)
6464
6924
  };
6465
6925
 
6466
6926
  const barKeys = [
@@ -6475,7 +6935,7 @@ const barKeys = [
6475
6935
  "autoResize",
6476
6936
  "native"
6477
6937
  ];
6478
- const props$k = {
6938
+ const props$l = {
6479
6939
  tag: {
6480
6940
  type: String,
6481
6941
  default: "div"
@@ -6508,13 +6968,13 @@ const props$k = {
6508
6968
  type: Boolean,
6509
6969
  default: true
6510
6970
  },
6511
- barTo: props$l.to,
6512
- ...lodashEs.pick(props$l, barKeys)
6971
+ barTo: props$m.to,
6972
+ ...lodashEs.pick(props$m, barKeys)
6513
6973
  };
6514
6974
 
6515
6975
  /** @jsxImportSource vue */
6516
6976
 
6517
- const COMPONENT_NAME$t = 'vc-scroller-track';
6977
+ const COMPONENT_NAME$v = 'vc-scroller-track';
6518
6978
  const BAR_MAP = {
6519
6979
  vertical: {
6520
6980
  scroll: 'scrollTop',
@@ -6534,8 +6994,8 @@ const BAR_MAP = {
6534
6994
  }
6535
6995
  };
6536
6996
  const Track = /* @__PURE__ */ vue.defineComponent({
6537
- name: COMPONENT_NAME$t,
6538
- props: props$m,
6997
+ name: COMPONENT_NAME$v,
6998
+ props: props$n,
6539
6999
  emits: ['change'],
6540
7000
  setup(props, {
6541
7001
  emit,
@@ -6720,10 +7180,10 @@ const Track = /* @__PURE__ */ vue.defineComponent({
6720
7180
 
6721
7181
  /** @jsxImportSource vue */
6722
7182
 
6723
- const COMPONENT_NAME$s = 'vc-scroller-bar';
7183
+ const COMPONENT_NAME$u = 'vc-scroller-bar';
6724
7184
  const Bar = /* @__PURE__ */ vue.defineComponent({
6725
- name: COMPONENT_NAME$s,
6726
- props: props$l,
7185
+ name: COMPONENT_NAME$u,
7186
+ props: props$m,
6727
7187
  emits: ['change'],
6728
7188
  setup(props, {
6729
7189
  emit,
@@ -6936,7 +7396,7 @@ const useScroller = (expose) => {
6936
7396
 
6937
7397
  /** @jsxImportSource vue */
6938
7398
 
6939
- const COMPONENT_NAME$r = 'vc-scroller';
7399
+ const COMPONENT_NAME$t = 'vc-scroller';
6940
7400
 
6941
7401
  /**
6942
7402
  * 作为备选方案,目前推荐使用ScrollerWheel
@@ -6947,8 +7407,8 @@ const COMPONENT_NAME$r = 'vc-scroller';
6947
7407
  * 2. 增加了一层嵌套
6948
7408
  */
6949
7409
  const Scroller = /* @__PURE__ */ vue.defineComponent({
6950
- name: COMPONENT_NAME$r,
6951
- props: props$k,
7410
+ name: COMPONENT_NAME$t,
7411
+ props: props$l,
6952
7412
  emits: ['scroll'],
6953
7413
  setup(props, {
6954
7414
  slots,
@@ -7008,7 +7468,7 @@ const Scroller = /* @__PURE__ */ vue.defineComponent({
7008
7468
 
7009
7469
  /** @jsxImportSource vue */
7010
7470
 
7011
- const COMPONENT_NAME$q = 'vc-scroller-wheel';
7471
+ const COMPONENT_NAME$s = 'vc-scroller-wheel';
7012
7472
 
7013
7473
  /**
7014
7474
  * 为减少一层嵌套,为去除滚动bar的抖动,使用wheel模拟
@@ -7030,8 +7490,8 @@ const COMPONENT_NAME$q = 'vc-scroller-wheel';
7030
7490
  * 设置scrollTop不会reflow和repaint,不需要考虑transfrom来改变content(transform也只在draw完成)
7031
7491
  */
7032
7492
  const ScrollerWheel = /* @__PURE__ */ vue.defineComponent({
7033
- name: COMPONENT_NAME$q,
7034
- props: props$k,
7493
+ name: COMPONENT_NAME$s,
7494
+ props: props$l,
7035
7495
  emits: ['scroll'],
7036
7496
  setup(props, {
7037
7497
  slots,
@@ -7135,9 +7595,9 @@ const ScrollerWheel = /* @__PURE__ */ vue.defineComponent({
7135
7595
 
7136
7596
  /** @jsxImportSource vue */
7137
7597
 
7138
- const COMPONENT_NAME$p = 'vc-recycle-list-scroll-state';
7598
+ const COMPONENT_NAME$r = 'vc-recycle-list-scroll-state';
7139
7599
  const ScrollState = /* @__PURE__ */ vue.defineComponent({
7140
- name: COMPONENT_NAME$p,
7600
+ name: COMPONENT_NAME$r,
7141
7601
  setup(_, {
7142
7602
  slots
7143
7603
  }) {
@@ -7208,7 +7668,7 @@ const STATUS_MAP = {
7208
7668
  }
7209
7669
  };
7210
7670
 
7211
- const props$j = {
7671
+ const props$k = {
7212
7672
  inverted: {
7213
7673
  type: Boolean,
7214
7674
  default: false
@@ -7267,13 +7727,13 @@ const useDirectionKeys = () => {
7267
7727
 
7268
7728
  /** @jsxImportSource vue */
7269
7729
 
7270
- const COMPONENT_NAME$o = 'vc-recycle-list-container';
7730
+ const COMPONENT_NAME$q = 'vc-recycle-list-container';
7271
7731
 
7272
7732
  // TODO: 抽离
7273
7733
  const transformKey = $__namespace.prefixStyle('transform').camel;
7274
7734
  const Container = /* @__PURE__ */ vue.defineComponent({
7275
- name: COMPONENT_NAME$o,
7276
- props: props$j,
7735
+ name: COMPONENT_NAME$q,
7736
+ props: props$k,
7277
7737
  emits: ['refresh'],
7278
7738
  setup(props, {
7279
7739
  slots
@@ -7370,16 +7830,16 @@ const Container = /* @__PURE__ */ vue.defineComponent({
7370
7830
 
7371
7831
  /** @jsxImportSource vue */
7372
7832
 
7373
- const COMPONENT_NAME$n = 'vc-recycle-list-item';
7833
+ const COMPONENT_NAME$p = 'vc-recycle-list-item';
7374
7834
  const Item = /* @__PURE__ */ vue.defineComponent({
7375
- name: COMPONENT_NAME$n,
7835
+ name: COMPONENT_NAME$p,
7376
7836
  props: {
7377
7837
  vertical: {
7378
7838
  type: Boolean,
7379
7839
  default: true
7380
7840
  }
7381
7841
  },
7382
- emits: ['resize'],
7842
+ emits: ['resize', 'change'],
7383
7843
  setup(_, {
7384
7844
  emit,
7385
7845
  slots
@@ -7391,9 +7851,10 @@ const Item = /* @__PURE__ */ vue.defineComponent({
7391
7851
  const handleResize = () => {
7392
7852
  const v = current.value.getBoundingClientRect()[K.size];
7393
7853
  const changed = offsetSize.value != v;
7394
- if (hasInitial && changed) {
7854
+ if (changed) {
7395
7855
  offsetSize.value = v;
7396
- emit('resize');
7856
+ hasInitial && emit('resize', v);
7857
+ emit('change', v);
7397
7858
  }
7398
7859
  hasInitial = true;
7399
7860
  };
@@ -7414,10 +7875,10 @@ const Item = /* @__PURE__ */ vue.defineComponent({
7414
7875
 
7415
7876
  /** @jsxImportSource vue */
7416
7877
 
7417
- const COMPONENT_NAME$m = 'vc-recycle-list';
7878
+ const COMPONENT_NAME$o = 'vc-recycle-list';
7418
7879
  const RecycleList = /* @__PURE__ */ vue.defineComponent({
7419
- name: COMPONENT_NAME$m,
7420
- props: props$n,
7880
+ name: COMPONENT_NAME$o,
7881
+ props: props$o,
7421
7882
  emits: ['scroll'],
7422
7883
  setup(props, {
7423
7884
  slots,
@@ -7961,18 +8422,18 @@ const RecycleList = /* @__PURE__ */ vue.defineComponent({
7961
8422
 
7962
8423
  const MRecycleList = RecycleList;
7963
8424
 
7964
- const props$i = {
8425
+ const props$j = {
7965
8426
  tag: {
7966
8427
  type: String,
7967
8428
  default: "div"
7968
8429
  }
7969
8430
  };
7970
8431
 
7971
- const COMPONENT_NAME$l = "vc-resizer";
8432
+ const COMPONENT_NAME$n = "vc-resizer";
7972
8433
  const Resizer = vue.defineComponent({
7973
- name: COMPONENT_NAME$l,
7974
- props: props$i,
7975
- emit: ["resize"],
8434
+ name: COMPONENT_NAME$n,
8435
+ props: props$j,
8436
+ emit: ["resize", "change"],
7976
8437
  setup(props, { emit, slots }) {
7977
8438
  const width = vue.ref(0);
7978
8439
  const height = vue.ref(0);
@@ -7998,8 +8459,9 @@ const Resizer = vue.defineComponent({
7998
8459
  const widthChanged = width.value != width$;
7999
8460
  heightChanged && (height.value = height$);
8000
8461
  widthChanged && (width.value = width$);
8001
- if (hasInitial && (heightChanged || widthChanged)) {
8002
- emit("resize", currentExposed.value);
8462
+ if (heightChanged || widthChanged) {
8463
+ hasInitial && emit("resize", currentExposed.value);
8464
+ emit("change", currentExposed.value);
8003
8465
  }
8004
8466
  hasInitial = true;
8005
8467
  };
@@ -8026,7 +8488,7 @@ const MResizer = Resizer;
8026
8488
 
8027
8489
  const MScroller = Scroller;
8028
8490
 
8029
- const props$h = {
8491
+ const props$i = {
8030
8492
  tag: {
8031
8493
  type: String,
8032
8494
  default: "div"
@@ -8035,10 +8497,10 @@ const props$h = {
8035
8497
 
8036
8498
  /** @jsxImportSource vue */
8037
8499
 
8038
- const COMPONENT_NAME$k = 'vc-select';
8500
+ const COMPONENT_NAME$m = 'vc-select';
8039
8501
  const Select = /* @__PURE__ */ vue.defineComponent({
8040
- name: COMPONENT_NAME$k,
8041
- props: props$h,
8502
+ name: COMPONENT_NAME$m,
8503
+ props: props$i,
8042
8504
  setup(props, {
8043
8505
  slots
8044
8506
  }) {
@@ -8052,7 +8514,7 @@ const Select = /* @__PURE__ */ vue.defineComponent({
8052
8514
 
8053
8515
  const MSelect = Select;
8054
8516
 
8055
- const props$g = {
8517
+ const props$h = {
8056
8518
  tag: {
8057
8519
  type: String,
8058
8520
  default: "div"
@@ -8061,10 +8523,10 @@ const props$g = {
8061
8523
 
8062
8524
  /** @jsxImportSource vue */
8063
8525
 
8064
- const COMPONENT_NAME$j = 'vc-slider';
8526
+ const COMPONENT_NAME$l = 'vc-slider';
8065
8527
  const Slider = /* @__PURE__ */ vue.defineComponent({
8066
- name: COMPONENT_NAME$j,
8067
- props: props$g,
8528
+ name: COMPONENT_NAME$l,
8529
+ props: props$h,
8068
8530
  setup(props, {
8069
8531
  slots
8070
8532
  }) {
@@ -8078,7 +8540,7 @@ const Slider = /* @__PURE__ */ vue.defineComponent({
8078
8540
 
8079
8541
  const MSlider = Slider;
8080
8542
 
8081
- const props$f = {
8543
+ const props$g = {
8082
8544
  tag: {
8083
8545
  type: String,
8084
8546
  default: "div"
@@ -8087,10 +8549,10 @@ const props$f = {
8087
8549
 
8088
8550
  /** @jsxImportSource vue */
8089
8551
 
8090
- const COMPONENT_NAME$i = 'vc-sort-list';
8552
+ const COMPONENT_NAME$k = 'vc-sort-list';
8091
8553
  const SortList = /* @__PURE__ */ vue.defineComponent({
8092
- name: COMPONENT_NAME$i,
8093
- props: props$f,
8554
+ name: COMPONENT_NAME$k,
8555
+ props: props$g,
8094
8556
  setup(props, {
8095
8557
  slots
8096
8558
  }) {
@@ -8104,7 +8566,7 @@ const SortList = /* @__PURE__ */ vue.defineComponent({
8104
8566
 
8105
8567
  const MSortList = SortList;
8106
8568
 
8107
- const props$e = {
8569
+ const props$f = {
8108
8570
  tag: {
8109
8571
  type: String,
8110
8572
  default: "div"
@@ -8113,10 +8575,10 @@ const props$e = {
8113
8575
 
8114
8576
  /** @jsxImportSource vue */
8115
8577
 
8116
- const COMPONENT_NAME$h = 'vc-steps';
8578
+ const COMPONENT_NAME$j = 'vc-steps';
8117
8579
  const Steps = /* @__PURE__ */ vue.defineComponent({
8118
- name: COMPONENT_NAME$h,
8119
- props: props$e,
8580
+ name: COMPONENT_NAME$j,
8581
+ props: props$f,
8120
8582
  setup(props, {
8121
8583
  slots
8122
8584
  }) {
@@ -8130,7 +8592,7 @@ const Steps = /* @__PURE__ */ vue.defineComponent({
8130
8592
 
8131
8593
  const MSteps = Steps;
8132
8594
 
8133
- const props$d = {
8595
+ const props$e = {
8134
8596
  tag: {
8135
8597
  type: String,
8136
8598
  default: "div"
@@ -8139,10 +8601,10 @@ const props$d = {
8139
8601
 
8140
8602
  /** @jsxImportSource vue */
8141
8603
 
8142
- const COMPONENT_NAME$g = 'vc-switch';
8604
+ const COMPONENT_NAME$i = 'vc-switch';
8143
8605
  const Switch = /* @__PURE__ */ vue.defineComponent({
8144
- name: COMPONENT_NAME$g,
8145
- props: props$d,
8606
+ name: COMPONENT_NAME$i,
8607
+ props: props$e,
8146
8608
  setup(props, {
8147
8609
  slots
8148
8610
  }) {
@@ -8156,7 +8618,7 @@ const Switch = /* @__PURE__ */ vue.defineComponent({
8156
8618
 
8157
8619
  const MSwitch = Switch;
8158
8620
 
8159
- const props$c = {
8621
+ const props$d = {
8160
8622
  tag: {
8161
8623
  type: String,
8162
8624
  default: "div"
@@ -8165,10 +8627,10 @@ const props$c = {
8165
8627
 
8166
8628
  /** @jsxImportSource vue */
8167
8629
 
8168
- const COMPONENT_NAME$f = 'vc-table';
8630
+ const COMPONENT_NAME$h = 'vc-table';
8169
8631
  const Table = /* @__PURE__ */ vue.defineComponent({
8170
- name: COMPONENT_NAME$f,
8171
- props: props$c,
8632
+ name: COMPONENT_NAME$h,
8633
+ props: props$d,
8172
8634
  setup(props, {
8173
8635
  slots
8174
8636
  }) {
@@ -8182,7 +8644,7 @@ const Table = /* @__PURE__ */ vue.defineComponent({
8182
8644
 
8183
8645
  const MTable = Table;
8184
8646
 
8185
- const props$b = {
8647
+ const props$c = {
8186
8648
  type: {
8187
8649
  type: String,
8188
8650
  validator: (v) => /^(line|card)$/.test(v),
@@ -8290,7 +8752,7 @@ const useTabs = (options = {}) => {
8290
8752
  if (!item) return;
8291
8753
  list.value.splice(list.value.indexOf(item.props), 1);
8292
8754
  };
8293
- vue.provide("tabs", {
8755
+ vue.provide("vc-tabs", {
8294
8756
  props,
8295
8757
  currentValue,
8296
8758
  refresh,
@@ -8337,10 +8799,10 @@ const useTabs = (options = {}) => {
8337
8799
 
8338
8800
  /** @jsxImportSource vue */
8339
8801
 
8340
- const COMPONENT_NAME$e = 'vc-tabs';
8802
+ const COMPONENT_NAME$g = 'vc-tabs';
8341
8803
  const Tabs = /* @__PURE__ */ vue.defineComponent({
8342
- name: COMPONENT_NAME$e,
8343
- props: props$b,
8804
+ name: COMPONENT_NAME$g,
8805
+ props: props$c,
8344
8806
  emits: ['update:modelValue', 'change', 'click'],
8345
8807
  setup(props, {
8346
8808
  slots
@@ -8505,7 +8967,7 @@ const Tabs = /* @__PURE__ */ vue.defineComponent({
8505
8967
  }
8506
8968
  });
8507
8969
 
8508
- const props$a = {
8970
+ const props$b = {
8509
8971
  value: {
8510
8972
  type: [String, Number]
8511
8973
  },
@@ -8532,7 +8994,7 @@ const useTabsPane = () => {
8532
8994
  const { props } = instance;
8533
8995
  const currentValue = vue.ref(void 0);
8534
8996
  const isLoaded = vue.ref(false);
8535
- const tabs = vue.inject("tabs", {});
8997
+ const tabs = vue.inject("vc-tabs", {});
8536
8998
  const isActive = vue.computed(() => {
8537
8999
  const state = tabs.currentValue.value === (props.value || currentValue.value);
8538
9000
  if (!isLoaded.value && state) {
@@ -8587,10 +9049,10 @@ const useTabsPane = () => {
8587
9049
 
8588
9050
  /** @jsxImportSource vue */
8589
9051
 
8590
- const COMPONENT_NAME$d = 'vc-tabs-pane';
9052
+ const COMPONENT_NAME$f = 'vc-tabs-pane';
8591
9053
  const TabsPane = /* @__PURE__ */ vue.defineComponent({
8592
- name: COMPONENT_NAME$d,
8593
- props: props$a,
9054
+ name: COMPONENT_NAME$f,
9055
+ props: props$b,
8594
9056
  setup(_, {
8595
9057
  slots
8596
9058
  }) {
@@ -8605,8 +9067,329 @@ const TabsPane = /* @__PURE__ */ vue.defineComponent({
8605
9067
  }
8606
9068
  });
8607
9069
 
8608
- const MTabs = Tabs;
8609
- const MTabsPane = TabsPane;
9070
+ const props$a = {
9071
+ ...props$c,
9072
+ theme: {
9073
+ type: String,
9074
+ default: "light",
9075
+ validator: (v) => /(light|dark)/.test(v)
9076
+ },
9077
+ barStyle: {
9078
+ type: [Object, Array],
9079
+ default: () => ({})
9080
+ },
9081
+ autoAfloatWidth: {
9082
+ type: Boolean,
9083
+ default: true
9084
+ },
9085
+ average: {
9086
+ type: Boolean,
9087
+ default: true
9088
+ },
9089
+ showWrapper: {
9090
+ type: Boolean,
9091
+ default: true
9092
+ },
9093
+ sticky: {
9094
+ type: Boolean,
9095
+ default: false
9096
+ },
9097
+ offsetTop: {
9098
+ type: Number,
9099
+ default: 0
9100
+ },
9101
+ showStep: {
9102
+ type: Boolean,
9103
+ default: false
9104
+ }
9105
+ };
9106
+
9107
+ /** @jsxImportSource vue */
9108
+
9109
+ const COMPONENT_NAME$e = 'vcm-tabs';
9110
+ const MTabs = /* @__PURE__ */ vue.defineComponent({
9111
+ name: COMPONENT_NAME$e,
9112
+ props: props$a,
9113
+ emits: ['update:modelValue', 'change', 'click'],
9114
+ setup(props, {
9115
+ slots
9116
+ }) {
9117
+ const instance = vue.getCurrentInstance();
9118
+ const wrapper = vue.ref(null);
9119
+ const content = vue.ref(null);
9120
+ const scroll = vue.ref(null);
9121
+ const nav = vue.ref(null);
9122
+ const top = vue.ref(0);
9123
+ const isFixed = vue.ref(false);
9124
+ const placeholderH = vue.ref(53);
9125
+ const startX = vue.ref(0);
9126
+ const isTouching = vue.ref(false);
9127
+ const scrollViewW = vue.ref(0); // 滚动容器宽度
9128
+ const scrollContentW = vue.ref(0); // 滚动内容宽度
9129
+ const baseX = vue.ref(0);
9130
+ const isDark = vue.computed(() => {
9131
+ return props.theme === 'dark';
9132
+ });
9133
+ const fixedStyle = vue.computed(() => {
9134
+ return isFixed.value ? {
9135
+ top: `${props.offsetTop}px`
9136
+ } : {};
9137
+ });
9138
+
9139
+ // eslint-disable-next-line prefer-const
9140
+ let tabs;
9141
+
9142
+ // TODO: 找到父层滚动条
9143
+ const handleScroll = lodashEs.throttle(() => {
9144
+ isFixed.value = document.scrollingElement.scrollTop + props.offsetTop > top.value;
9145
+ }, 100);
9146
+ const handleTouchstart = e => {
9147
+ isTouching.value = true;
9148
+ startX.value = e.touches[0].pageX;
9149
+ baseX.value = tabs.scrollOffset.value;
9150
+ };
9151
+ const handleTouchmove = lodashEs.throttle(e => {
9152
+ const touchPageX = e.touches[0].pageX;
9153
+ // 与touchstart时触点位置的距离偏移值,大于0时为触点向右移,反之向左
9154
+ const changedX = touchPageX - startX.value;
9155
+ if (changedX > 0) {
9156
+ if (tabs.scrollOffset.value >= 0) {
9157
+ tabs.scrollOffset.value = 0;
9158
+ return;
9159
+ }
9160
+ } else if (Math.abs(tabs.scrollOffset.value) + scrollViewW.value >= scrollContentW.value) {
9161
+ tabs.scrollOffset.value = -(scrollContentW.value - scrollViewW.value);
9162
+ return;
9163
+ }
9164
+ tabs.scrollOffset.value = baseX.value + touchPageX - startX.value;
9165
+ }, 17);
9166
+ const handleTouchend = () => {
9167
+ isTouching.value = false;
9168
+ // TODO: 惯性滚动、回弹 (体验优化)
9169
+ };
9170
+ const handleStep = flag => {
9171
+ if (!tabs.scrollable.value) return;
9172
+ const moveX = flag * scrollViewW.value;
9173
+ let offsetX = tabs.scrollOffset.value + moveX;
9174
+ if (offsetX < -(scrollContentW.value - scrollViewW.value) || offsetX > 0) {
9175
+ offsetX = flag === -1 ? -(scrollContentW.value - scrollViewW.value) : 0;
9176
+ }
9177
+ tabs.scrollOffset.value = offsetX;
9178
+ };
9179
+
9180
+ /**
9181
+ * 使用Resize时, 切换页面失效,换种方案
9182
+ */
9183
+ const refreshTop = lodashEs.debounce(() => {
9184
+ if (props.sticky) {
9185
+ top.value = content.value.offsetTop - placeholderH.value;
9186
+ isFixed.value = document.scrollingElement.scrollTop + props.offsetTop > top.value;
9187
+ }
9188
+ }, 250, {
9189
+ leading: true,
9190
+ trailing: true
9191
+ });
9192
+
9193
+ /**
9194
+ * 将选中的item滚动至可视区(尽量往中间靠)
9195
+ */
9196
+ const scrollToActive = () => {
9197
+ if (!tabs.scrollable.value) return;
9198
+ const activeEl = instance.vnode.el.querySelector(`.vcm-tabs__item[data-id="${tabs.currentValue.value}"]`);
9199
+ if (!activeEl) return;
9200
+ const contentEl = nav.value;
9201
+ const activeRect = activeEl.getBoundingClientRect();
9202
+ const viewRect = scroll.value.getBoundingClientRect();
9203
+ const contentRect = contentEl.getBoundingClientRect();
9204
+ let offset = 0;
9205
+ if (activeRect.width < viewRect.width) {
9206
+ // targetOffset为最理想的情况下,可以滚动到正中间,此时activeEl距scrollView的左右边距
9207
+ const targetOffset = (viewRect.width - activeRect.width) / 2;
9208
+ // offsetLeft其实等价于activeEl.offsetLeft,
9209
+ // 但是调试时发现这两个值在小数位会有差距,offsetLeft一直是整数,所以还是决定用下面这种方式计算offsetLeft
9210
+ const offsetLeft = activeRect.left - contentRect.left;
9211
+ if (offsetLeft - viewRect.left <= targetOffset) {
9212
+ // 左边距离不足以到正中间的情况
9213
+ offset = 0;
9214
+ } else if (contentRect.right - activeRect.right <= targetOffset) {
9215
+ // 右边距离不足以到正中间的情况
9216
+ offset = viewRect.width - contentRect.width; // 负值
9217
+ } else {
9218
+ offset = targetOffset - offsetLeft; // 可以滚动到正中间的理想情况
9219
+ }
9220
+ }
9221
+ tabs.scrollOffset.value = offset;
9222
+ };
9223
+ const operateDOMScrollEvents = type => {
9224
+ const fn = type === 'add' ? window.addEventListener : window.removeEventListener;
9225
+ fn('scroll', handleScroll);
9226
+ fn('touchstart', handleTouchstart, false);
9227
+ fn('touchmove', handleTouchmove, false);
9228
+ fn('touchend', handleTouchend, false);
9229
+ };
9230
+
9231
+ /**
9232
+ * 处理是否需要滚动
9233
+ */
9234
+ const refreshScroll = () => {
9235
+ const viewEl = scroll.value;
9236
+ scrollViewW.value = viewEl.offsetWidth;
9237
+ scrollContentW.value = nav.value.offsetWidth;
9238
+ if (scrollContentW.value > scrollViewW.value) {
9239
+ operateDOMScrollEvents('remove');
9240
+ operateDOMScrollEvents('add');
9241
+ tabs.scrollable.value = true;
9242
+ } else if (tabs.scrollable.value) {
9243
+ operateDOMScrollEvents('remove');
9244
+ tabs.scrollable.value = false;
9245
+ }
9246
+ tabs.scrollable.value && scrollToActive();
9247
+ };
9248
+
9249
+ /**
9250
+ * 刷新当前标签底下的滑块位置
9251
+ */
9252
+ const refreshAfloat = () => {
9253
+ if (!props.showWrapper) return;
9254
+ vue.nextTick(() => {
9255
+ const index = tabs.getTabIndex(tabs.currentValue.value);
9256
+ if (instance.isUnmounted) return;
9257
+ const items = nav.value.querySelectorAll(`.vcm-tabs__item`);
9258
+ const $ = items[index];
9259
+
9260
+ // 暂时写死42
9261
+ tabs.afloatWidth.value = $ ? isDark.value ? 20 : props.autoAfloatWidth ? $.querySelector('span').offsetWidth : $.offsetWidth : 0;
9262
+ if (!Array.from(items).length) return;
9263
+ let offset = 0;
9264
+ const basicOffset = $ ? ($.offsetWidth - tabs.afloatWidth.value) / 2 : 0;
9265
+ if (index > 0) {
9266
+ for (let i = 0; i < index; i++) {
9267
+ offset += parseFloat(items[i].offsetWidth);
9268
+ }
9269
+ }
9270
+ tabs.afloatOffset.value = offset + basicOffset;
9271
+ refreshScroll();
9272
+ });
9273
+ };
9274
+
9275
+ /**
9276
+ * TODO: 在height: 100%容器内滚动,让其带有粘性
9277
+ * @param type ~
9278
+ */
9279
+ const operateDOMEvents = type => {
9280
+ if (!props.sticky) return;
9281
+ const fn = type === 'add' ? window.addEventListener : window.removeEventListener;
9282
+ fn('scroll', handleScroll);
9283
+ };
9284
+ tabs = useTabs({
9285
+ content,
9286
+ wrapper,
9287
+ refreshAfloat,
9288
+ refreshScroll,
9289
+ scrollToActive
9290
+ });
9291
+ const scrollStyle = vue.computed(() => {
9292
+ return {
9293
+ transition: isTouching.value ? '' : 'transform 300ms ease-in-out',
9294
+ transform: `translate3d(${tabs.scrollOffset.value}px, 0, 0)`
9295
+ };
9296
+ });
9297
+ vue.onMounted(() => {
9298
+ refreshTop();
9299
+ operateDOMEvents('add');
9300
+ vue.nextTick(refreshScroll);
9301
+ });
9302
+ vue.onUpdated(refreshTop);
9303
+ vue.onUnmounted(() => {
9304
+ operateDOMEvents('remove');
9305
+ operateDOMScrollEvents('remove');
9306
+ });
9307
+ vue.watch(() => props.theme, refreshAfloat);
9308
+ vue.watch(() => props.average, refreshAfloat);
9309
+ vue.watch(() => props.showStep, () => vue.nextTick(refreshScroll));
9310
+ return () => {
9311
+ return vue.createVNode("div", {
9312
+ "class": [tabs.classes.value, 'vcm-tabs']
9313
+ }, [props.showWrapper && vue.createVNode("div", {
9314
+ "ref": wrapper,
9315
+ "style": [props.barStyle, fixedStyle.value],
9316
+ "class": [{
9317
+ 'is-fixed': isFixed
9318
+ }, 'vcm-tabs__bar']
9319
+ }, [vue.createVNode("slot", {
9320
+ "name": "prepend"
9321
+ }, null), slots.prepend?.(), props.showStep && tabs.scrollable.value && vue.createVNode("div", {
9322
+ "class": "vcm-tabs__step is-left",
9323
+ "onClick": () => handleStep(1)
9324
+ }, [vue.createVNode(Icon, {
9325
+ "type": "left"
9326
+ }, null)]), vue.createVNode("div", {
9327
+ "ref": scroll,
9328
+ "class": "vcm-tabs__scroll"
9329
+ }, [vue.createVNode("div", {
9330
+ "ref": nav,
9331
+ "style": scrollStyle.value,
9332
+ "class": "vcm-tabs__nav"
9333
+ }, [props.afloat && vue.createVNode("div", {
9334
+ "style": tabs.afloatStyle.value,
9335
+ "class": "vcm-tabs__afloat"
9336
+ }, null), tabs.list.value.map((item, index) => {
9337
+ return vue.createVNode("div", {
9338
+ "key": index,
9339
+ "data-id": item.value,
9340
+ "class": [{
9341
+ 'is-active': (item.value || index) == tabs.currentValue.value,
9342
+ 'is-average': props.average
9343
+ }, 'vcm-tabs__item'],
9344
+ "onClick": () => tabs.handleChange(index)
9345
+ }, [slots.label ? slots.label({
9346
+ it: item,
9347
+ index
9348
+ }) : typeof item.label === 'string' ? vue.createVNode("span", {
9349
+ "innerHTML": item.label
9350
+ }, null) : typeof item.label === 'function' && vue.createVNode(Customer, {
9351
+ "render": item.label,
9352
+ "it": item,
9353
+ "index": index
9354
+ }, null)]);
9355
+ })])]), props.showStep && tabs.scrollable.value && vue.createVNode("div", {
9356
+ "class": "vcm-tabs__step is-right",
9357
+ "onClick": () => handleStep(-1)
9358
+ }, [vue.createVNode(Icon, {
9359
+ "type": "right"
9360
+ }, null)]), slots.append?.()]), isFixed.value && vue.createVNode("div", {
9361
+ "style": {
9362
+ height: `${placeholderH.value}px`
9363
+ },
9364
+ "class": "vcm-tabs__placeholder"
9365
+ }, null), vue.createVNode("div", {
9366
+ "ref": content,
9367
+ "style": tabs.contentStyle.value,
9368
+ "class": "vcm-tabs__content"
9369
+ }, [slots.default?.()])]);
9370
+ };
9371
+ }
9372
+ });
9373
+
9374
+ /** @jsxImportSource vue */
9375
+
9376
+ const COMPONENT_NAME$d = 'vcm-tabs-pane';
9377
+ const MTabsPane = /* @__PURE__ */ vue.defineComponent({
9378
+ name: COMPONENT_NAME$d,
9379
+ props: props$b,
9380
+ setup(_, {
9381
+ slots
9382
+ }) {
9383
+ const tabsPane = useTabsPane();
9384
+ return () => {
9385
+ return vue.createVNode("div", {
9386
+ "class": "vcm-tabs-pane",
9387
+ "style": tabsPane.style.value,
9388
+ "name": tabsPane.currentValue.value
9389
+ }, [tabsPane.isReady && slots.default?.()]);
9390
+ };
9391
+ }
9392
+ });
8610
9393
 
8611
9394
  const props$9 = {
8612
9395
  tag: {
@@ -9043,13 +9826,15 @@ exports.Chart = Chart;
9043
9826
  exports.Checkbox = Checkbox;
9044
9827
  exports.Clipboard = Clipboard;
9045
9828
  exports.Collapse = Collapse;
9829
+ exports.CollapseItem = CollapseItem;
9046
9830
  exports.ColorPicker = ColorPicker;
9047
9831
  exports.Countdown = Countdown;
9048
9832
  exports.Customer = Customer;
9049
9833
  exports.DatePicker = DatePicker;
9050
9834
  exports.Debounce = Debounce;
9051
9835
  exports.Divider = Divider;
9052
- exports.Drawer = Drawer;
9836
+ exports.Drawer = drawer;
9837
+ exports.DrawerView = DrawerView;
9053
9838
  exports.Dropdown = Dropdown;
9054
9839
  exports.Editor = Editor;
9055
9840
  exports.Expand = Expand;
@@ -9081,13 +9866,14 @@ exports.MChart = MChart;
9081
9866
  exports.MCheckbox = MCheckbox;
9082
9867
  exports.MClipboard = MClipboard;
9083
9868
  exports.MCollapse = MCollapse;
9869
+ exports.MCollapseItem = MCollapseItem;
9084
9870
  exports.MColorPicker = MColorPicker;
9085
9871
  exports.MCountdown = MCountdown;
9086
9872
  exports.MCustomer = MCustomer;
9087
9873
  exports.MDatePicker = MDatePicker;
9088
9874
  exports.MDebounce = Debounce;
9089
9875
  exports.MDivider = MDivider;
9090
- exports.MDrawer = MDrawer;
9876
+ exports.MDrawerView = MDrawerView;
9091
9877
  exports.MDropdown = MDropdown;
9092
9878
  exports.MEditor = MEditor;
9093
9879
  exports.MExpand = MExpand;