@deot/vc-components 1.0.46 → 1.0.48

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.
@@ -89,6 +89,38 @@ var VcComponents = (function (exports, vue) {
89
89
 
90
90
  const MActionSheet = ActionSheet;
91
91
 
92
+ const props$1s = {
93
+ modelValue: {
94
+ type: Boolean,
95
+ default: false
96
+ },
97
+ zIndex: {
98
+ type: [Number, String],
99
+ default: 1
100
+ },
101
+ // TODO: left/right
102
+ placement: {
103
+ type: String,
104
+ default: "top"
105
+ },
106
+ disabled: {
107
+ type: Boolean,
108
+ default: false
109
+ },
110
+ fixed: {
111
+ type: Boolean,
112
+ default: true
113
+ },
114
+ offset: {
115
+ type: Number,
116
+ default: 0
117
+ },
118
+ // -> 固钉始终保持在容器内, 超过范围则隐藏(请注意容器避免出现滚动条) 仅fixed为true有效
119
+ target: {
120
+ type: String
121
+ }
122
+ };
123
+
92
124
  const IS_SERVER$3 = typeof window === "undefined";
93
125
 
94
126
  const hasClass = (el, cls) => {
@@ -186,7 +218,7 @@ var VcComponents = (function (exports, vue) {
186
218
  return !!(overflow.match(/(scroll|auto)/) || className?.test(el.className));
187
219
  };
188
220
 
189
- const getScroller = (el, options) => {
221
+ const getScroller$1 = (el, options) => {
190
222
  if (IS_SERVER$3 || !el) return null;
191
223
  let parent = el;
192
224
  while (parent) {
@@ -305,44 +337,45 @@ var VcComponents = (function (exports, vue) {
305
337
  return target;
306
338
  };
307
339
 
308
- const props$1s = {
309
- zIndex: {
310
- type: [Number, String],
311
- default: 1
312
- },
313
- // TODO: left/right
314
- placement: {
315
- type: String,
316
- default: "top"
317
- },
318
- disabled: {
319
- type: Boolean,
320
- default: false
321
- },
322
- fixed: {
323
- type: Boolean,
324
- default: true
325
- },
326
- offset: {
327
- type: Number,
328
- default: 0
329
- },
330
- // -> 固钉始终保持在容器内, 超过范围则隐藏(请注意容器避免出现滚动条) 仅fixed为true有效
331
- target: {
332
- type: String
333
- }
340
+ let scrollBarWidth;
341
+ const getScrollBarWidth = () => {
342
+ if (scrollBarWidth !== void 0) return scrollBarWidth;
343
+ const outer = document.createElement("div");
344
+ outer.className = "vc-scrollbar__wrap";
345
+ outer.style.visibility = "hidden";
346
+ outer.style.width = "100px";
347
+ outer.style.position = "absolute";
348
+ outer.style.top = "-9999px";
349
+ document.body.appendChild(outer);
350
+ const widthNoScroll = outer.offsetWidth;
351
+ outer.style.overflow = "scroll";
352
+ const inner = document.createElement("div");
353
+ inner.style.width = "100%";
354
+ outer.appendChild(inner);
355
+ const widthWithScroll = inner.offsetWidth;
356
+ outer.parentNode?.removeChild?.(outer);
357
+ scrollBarWidth = widthNoScroll - widthWithScroll;
358
+ return scrollBarWidth;
359
+ };
360
+ const SCROLLER_WHEEL_REG = /vc-scroller-wheel/;
361
+ const getScroller = (el) => {
362
+ return getScroller$1(el, { className: SCROLLER_WHEEL_REG });
363
+ };
364
+ const isWheel = (el) => {
365
+ return SCROLLER_WHEEL_REG.test(el?.className || "");
334
366
  };
335
367
 
336
368
  /** @jsxImportSource vue */
337
369
 
338
370
  const COMPONENT_NAME$27 = 'vc-affix';
339
- const SCROLLER_WHEEL_REG = /vc-scroller-wheel/;
340
371
  const Affix = /* @__PURE__ */ vue.defineComponent({
341
372
  name: COMPONENT_NAME$27,
373
+ emits: ['update:modelValue'],
342
374
  props: props$1s,
343
375
  setup(props, {
344
376
  slots,
345
- expose
377
+ expose,
378
+ emit
346
379
  }) {
347
380
  const scrollerInstance = vue.inject('vc-scroller', null);
348
381
  const scroller = vue.shallowRef(); // 当前元素所在的滚动容器
@@ -358,9 +391,7 @@ var VcComponents = (function (exports, vue) {
358
391
  const isActive = vue.ref(false);
359
392
  const transformY = vue.ref(0);
360
393
  const windowHeight = vue.ref(window.innerHeight);
361
- const isVcScrollerWheel = vue.computed(() => {
362
- return SCROLLER_WHEEL_REG.test(scroller.value?.className || '');
363
- });
394
+ const isVcScrollerWheel = vue.computed(() => isWheel(scroller.value));
364
395
  const currentStyle = vue.computed(() => {
365
396
  if (!isActive.value) return {};
366
397
  return {
@@ -381,7 +412,8 @@ var VcComponents = (function (exports, vue) {
381
412
  };
382
413
  });
383
414
  const setCurrentRect = () => {
384
- const rect = current.value.getBoundingClientRect();
415
+ const rect = current.value?.getBoundingClientRect?.();
416
+ if (!rect) return;
385
417
  Object.assign(currentRect, {
386
418
  top: rect.top,
387
419
  bottom: rect.bottom,
@@ -408,7 +440,7 @@ var VcComponents = (function (exports, vue) {
408
440
  transformY.value = Math.min(containerRect.bottom - currentHeightOffset, 0) + transformOffsetY;
409
441
  } else {
410
442
  isActive.value = currentRect.bottom - containerRect.top >= containerRect.height - props.offset;
411
- transformY.value = Math.max(containerRect.height - containerRect.top - currentHeightOffset, 0) + transformOffsetY;
443
+ transformY.value = transformOffsetY;
412
444
  }
413
445
  };
414
446
  const setFixedStatus = () => {
@@ -435,36 +467,58 @@ var VcComponents = (function (exports, vue) {
435
467
  }
436
468
  }
437
469
  };
470
+ const offScroll = handler => {
471
+ if (isVcScrollerWheel.value) {
472
+ scrollerInstance?.off(handler);
473
+ } else {
474
+ scroller.value?.removeEventListener('scroll', handler);
475
+ }
476
+ };
477
+ const onScroll = (handler, options) => {
478
+ // nextTick目的在与onMounted后执行
479
+ vue.nextTick(() => {
480
+ if (isVcScrollerWheel.value) {
481
+ scrollerInstance?.on(handler);
482
+ } else {
483
+ scroller.value?.addEventListener('scroll', handler);
484
+ }
485
+ options?.first && handler();
486
+ });
487
+ return () => offScroll(handler);
488
+ };
438
489
  const refresh = () => {
490
+ if (props.disabled) return;
439
491
  setCurrentRect();
440
492
  scroller.value instanceof Window || props.fixed ? setFixedStatus() : setAbsoluteStatus();
493
+ emit('update:modelValue', isActive.value);
441
494
  };
442
495
  vue.onMounted(() => {
443
496
  if (typeof props.target === 'string') {
444
497
  base.value = document.querySelector(props.target) ?? void 0;
445
498
  }
446
499
  !base.value && (base.value = document.documentElement);
447
- scroller.value = getScroller(current.value, {
448
- className: SCROLLER_WHEEL_REG
500
+ scroller.value = getScroller(current.value);
501
+ onScroll(refresh, {
502
+ first: true
449
503
  });
450
- if (isVcScrollerWheel.value) {
451
- scrollerInstance?.on(refresh);
452
- } else {
453
- scroller.value?.addEventListener('scroll', refresh);
454
- }
455
- refresh();
456
- });
457
- vue.onBeforeUnmount(() => {
458
- if (isVcScrollerWheel.value) {
459
- scrollerInstance?.off(refresh);
460
- } else {
461
- scroller.value?.removeEventListener('scroll', refresh);
462
- }
463
504
  });
505
+ vue.onBeforeUnmount(() => offScroll(refresh));
464
506
  expose({
465
- refresh
507
+ refresh,
508
+ onScroll,
509
+ offScroll
510
+ });
511
+ vue.provide('vc-affix', {
512
+ props,
513
+ isActive,
514
+ refresh,
515
+ onScroll,
516
+ offScroll
466
517
  });
467
518
  return () => {
519
+ if (props.disabled) return slots?.default?.({
520
+ active: false
521
+ });
468
522
  return vue.createVNode("div", {
469
523
  "ref": current,
470
524
  "class": "vc-affix",
@@ -9278,7 +9332,8 @@ var VcComponents = (function (exports, vue) {
9278
9332
  nullValue: {
9279
9333
  type: [Number, String, Object],
9280
9334
  default: void 0
9281
- }
9335
+ },
9336
+ label: String
9282
9337
  };
9283
9338
 
9284
9339
  const props$18 = {
@@ -14390,27 +14445,6 @@ var VcComponents = (function (exports, vue) {
14390
14445
  }
14391
14446
  };
14392
14447
 
14393
- let scrollBarWidth;
14394
- const getScrollBarWidth = () => {
14395
- if (scrollBarWidth !== void 0) return scrollBarWidth;
14396
- const outer = document.createElement("div");
14397
- outer.className = "vc-scrollbar__wrap";
14398
- outer.style.visibility = "hidden";
14399
- outer.style.width = "100px";
14400
- outer.style.position = "absolute";
14401
- outer.style.top = "-9999px";
14402
- document.body.appendChild(outer);
14403
- const widthNoScroll = outer.offsetWidth;
14404
- outer.style.overflow = "scroll";
14405
- const inner = document.createElement("div");
14406
- inner.style.width = "100%";
14407
- outer.appendChild(inner);
14408
- const widthWithScroll = inner.offsetWidth;
14409
- outer.parentNode?.removeChild?.(outer);
14410
- scrollBarWidth = widthNoScroll - widthWithScroll;
14411
- return scrollBarWidth;
14412
- };
14413
-
14414
14448
  const barKeys$1 = [
14415
14449
  "always",
14416
14450
  "thumbMinSize",
@@ -21127,7 +21161,7 @@ var VcComponents = (function (exports, vue) {
21127
21161
  } else if (typeof wrapper === 'string') {
21128
21162
  scroller.value = document.querySelector(wrapper);
21129
21163
  } else {
21130
- scroller.value = getScroller(instance.vnode.el);
21164
+ scroller.value = getScroller$1(instance.vnode.el);
21131
21165
  }
21132
21166
  };
21133
21167
  const initPlaceholder = () => {
@@ -23247,7 +23281,7 @@ var VcComponents = (function (exports, vue) {
23247
23281
  "style": its.value.style,
23248
23282
  "animation": "y",
23249
23283
  "onMouseenter": () => isHover.value = true,
23250
- "onMuseleave": () => isHover.value = false,
23284
+ "onMouseleave": () => isHover.value = false,
23251
23285
  "onReady": () => emit('ready'),
23252
23286
  "onClose": () => emit('close'),
23253
23287
  "onVisibleChange": () => emit('visible-change', isActive.value),
@@ -23263,6 +23297,13 @@ var VcComponents = (function (exports, vue) {
23263
23297
  "readonly": true,
23264
23298
  "placeholder": its.value.attrs?.placeholder || '请选择'
23265
23299
  }, {
23300
+ prepend: slots.prepend || props.label ? () => {
23301
+ slots.prepend ? slots.prepend() : vue.createVNode("div", {
23302
+ "class": "vc-select__prepend"
23303
+ }, [vue.createVNode("span", {
23304
+ "class": "vc-select__label"
23305
+ }, [props.label])]);
23306
+ } : null,
23266
23307
  content: multiple.value && currentValue.value && currentValue.value.length > 0 ? () => {
23267
23308
  return vue.createVNode("div", {
23268
23309
  "class": [classes.value, 'vc-select__tags']
@@ -23284,7 +23325,7 @@ var VcComponents = (function (exports, vue) {
23284
23325
  }, [vue.createVNode(Icon, {
23285
23326
  "type": showClear.value ? 'clear' : icon.value,
23286
23327
  "class": [{
23287
- 'is-arrow': !showClear
23328
+ 'is-arrow': !showClear.value
23288
23329
  }, 'vc-select__icon'],
23289
23330
  "onClick": handleClear
23290
23331
  }, null)]);
@@ -29018,10 +29059,13 @@ var VcComponents = (function (exports, vue) {
29018
29059
  barStyle: [Object, String],
29019
29060
  contentStyle: [Object, String],
29020
29061
  barClass: [Object, String],
29021
- contentClass: [Object, String]
29062
+ contentClass: [Object, String],
29063
+ affixable: Boolean,
29064
+ affixOptions: Object
29022
29065
  };
29023
29066
 
29024
29067
  const useTabs = (options = {}) => {
29068
+ const affix = vue.inject("vc-affix", null);
29025
29069
  const instance = vue.getCurrentInstance();
29026
29070
  const { props, emit } = instance;
29027
29071
  const tabsId = vue.ref(getUid("tabs"));
@@ -29063,10 +29107,56 @@ var VcComponents = (function (exports, vue) {
29063
29107
  [`is-${props.theme}`]: !!props.theme
29064
29108
  };
29065
29109
  });
29110
+ const hasAnchor = vue.computed(() => {
29111
+ return list.value.some((item) => !!item.anchor);
29112
+ });
29066
29113
  const refresh = () => {
29067
29114
  options?.refreshAfloat?.();
29068
29115
  };
29069
- const handleChange = (index) => {
29116
+ let scrollToAnchorTimer;
29117
+ const scrollToAnchor = (anchor) => {
29118
+ if (!anchor) return;
29119
+ const el = document.querySelector(anchor);
29120
+ if (!el) return;
29121
+ const scroller = getScroller(instance.vnode.el);
29122
+ scrollIntoView(scroller, {
29123
+ duration: 250,
29124
+ from: scroller.scrollTop,
29125
+ to: scroller.scrollTop + el.getBoundingClientRect().top - scroller.getBoundingClientRect().top - (!affix || affix.props.placement !== "bottom" ? instance.vnode.el.offsetHeight : 0) - (affix && affix.props.placement !== "bottom" ? affix.props.offset : 0)
29126
+ });
29127
+ scrollToAnchorTimer && clearTimeout(scrollToAnchorTimer);
29128
+ scrollToAnchorTimer = setTimeout(() => scrollToAnchorTimer = null, 300);
29129
+ };
29130
+ const handleAffixScroll = () => {
29131
+ if (!hasAnchor.value || scrollToAnchorTimer) return;
29132
+ const scroller = getScroller(instance.vnode.el);
29133
+ const scrollTop = scroller?.scrollTop;
29134
+ if (typeof scrollTop !== "number") return;
29135
+ for (let i = 0; i < list.value.length; i++) {
29136
+ const nav = list.value[i];
29137
+ const anchor = nav.anchor;
29138
+ if (!anchor) continue;
29139
+ const el = document.querySelector(anchor);
29140
+ if (!el) continue;
29141
+ const elTop = el.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop;
29142
+ const nextNav = list.value[i + 1];
29143
+ let nextElTop;
29144
+ if (nextNav && nextNav.anchor) {
29145
+ const nextEl = document.querySelector(nextNav.anchor);
29146
+ if (nextEl) {
29147
+ nextElTop = nextEl.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop;
29148
+ }
29149
+ }
29150
+ const allowDistance = 2;
29151
+ if (scrollTop >= elTop - allowDistance && (typeof nextElTop === "undefined" || scrollTop < nextElTop - allowDistance)) {
29152
+ if (getTabIndex(currentValue.value) !== i) {
29153
+ handleChange(i, false);
29154
+ }
29155
+ break;
29156
+ }
29157
+ }
29158
+ };
29159
+ const handleChange = (index, scrollTo = true) => {
29070
29160
  if (timer.value) return;
29071
29161
  timer.value = setTimeout(() => timer.value = null, 300);
29072
29162
  const nav = list.value[index];
@@ -29075,7 +29165,7 @@ var VcComponents = (function (exports, vue) {
29075
29165
  emit("update:modelValue", currentValue.value);
29076
29166
  emit("change", currentValue.value);
29077
29167
  emit("click", currentValue.value);
29078
- nav.anchor && document.querySelector(nav.anchor)?.scrollIntoView?.({ behavior: "smooth" });
29168
+ scrollTo && scrollToAnchor(nav.anchor);
29079
29169
  };
29080
29170
  const handleResize = () => {
29081
29171
  if (instance.isUnmounted) return;
@@ -29085,10 +29175,13 @@ var VcComponents = (function (exports, vue) {
29085
29175
  vue.onMounted(() => {
29086
29176
  Resize.on(options.wrapper.value, handleResize);
29087
29177
  options.scrollToActive && vue.nextTick(options.scrollToActive);
29178
+ affix?.onScroll?.(handleAffixScroll);
29088
29179
  });
29089
29180
  vue.onBeforeUnmount(() => {
29090
29181
  Resize.off(options.wrapper.value, handleResize);
29091
29182
  timer.value && clearTimeout(timer.value);
29183
+ affix?.offScroll?.(handleAffixScroll);
29184
+ scrollToAnchorTimer && clearTimeout(scrollToAnchorTimer);
29092
29185
  });
29093
29186
  const add = (item, setValue) => {
29094
29187
  if (!item) return;