@deot/vc-components 1.0.47 → 1.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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",
@@ -14391,27 +14445,6 @@ var VcComponents = (function (exports, vue) {
14391
14445
  }
14392
14446
  };
14393
14447
 
14394
- let scrollBarWidth;
14395
- const getScrollBarWidth = () => {
14396
- if (scrollBarWidth !== void 0) return scrollBarWidth;
14397
- const outer = document.createElement("div");
14398
- outer.className = "vc-scrollbar__wrap";
14399
- outer.style.visibility = "hidden";
14400
- outer.style.width = "100px";
14401
- outer.style.position = "absolute";
14402
- outer.style.top = "-9999px";
14403
- document.body.appendChild(outer);
14404
- const widthNoScroll = outer.offsetWidth;
14405
- outer.style.overflow = "scroll";
14406
- const inner = document.createElement("div");
14407
- inner.style.width = "100%";
14408
- outer.appendChild(inner);
14409
- const widthWithScroll = inner.offsetWidth;
14410
- outer.parentNode?.removeChild?.(outer);
14411
- scrollBarWidth = widthNoScroll - widthWithScroll;
14412
- return scrollBarWidth;
14413
- };
14414
-
14415
14448
  const barKeys$1 = [
14416
14449
  "always",
14417
14450
  "thumbMinSize",
@@ -19866,7 +19899,14 @@ var VcComponents = (function (exports, vue) {
19866
19899
  labelStyle: [Object, String],
19867
19900
  labelClass: [Object, String],
19868
19901
  errorStyle: [Object, String],
19869
- errorClass: [Object, String]
19902
+ errorClass: [Object, String],
19903
+ // 给nestFormItem统一注入
19904
+ nestedContentStyle: [Object, String],
19905
+ nestedContentClass: [Object, String],
19906
+ nestedLabelStyle: [Object, String],
19907
+ nestedLabelClass: [Object, String],
19908
+ nestedErrorStyle: [Object, String],
19909
+ nestedErrorClass: [Object, String]
19870
19910
  };
19871
19911
 
19872
19912
  const useForm = (expose, options = {}) => {
@@ -20218,31 +20258,32 @@ var VcComponents = (function (exports, vue) {
20218
20258
  });
20219
20259
  const classes = vue.computed(() => {
20220
20260
  return {
20221
- "is-require": isRequired.value && props.asterisk,
20261
+ "is-required": isRequired.value && props.asterisk,
20222
20262
  "is-error": validateState.value === "error",
20223
20263
  "is-validating": validateState.value === "validating",
20224
20264
  "is-inline": form.props.inline,
20225
- "is-nest": isNest.value,
20265
+ "is-nested": isNested.value,
20226
20266
  "is-alone": !props.showMessage,
20227
20267
  // 用于单独去除form-item的默认margin_bottom
20228
20268
  [`is-${labelPosition.value}`]: true
20229
20269
  };
20230
20270
  });
20231
- const isNest = vue.computed(() => {
20271
+ const isNested = vue.computed(() => {
20232
20272
  return !!formItem.change;
20233
20273
  });
20234
- const isNestLast = vue.ref(false);
20274
+ const isNestedLast = vue.ref(false);
20235
20275
  const hasLabel = vue.computed(() => {
20236
20276
  return !!props.label || slots.label;
20237
20277
  });
20238
20278
  const labelStyle = vue.computed(() => {
20239
- const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNest.value ? 0 : form.props.labelWidth;
20279
+ const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNested.value ? 0 : form.props.labelWidth;
20240
20280
  return [
20241
20281
  {
20242
20282
  width: labelPosition.value !== "top" && labelWidth && labelWidth > 0 ? `${labelWidth}px` : "auto",
20243
20283
  textAlign: labelPosition.value === "top" ? "left" : labelPosition.value
20244
20284
  },
20245
20285
  form.props.labelStyle,
20286
+ isNested.value && form.props.nestedLabelStyle,
20246
20287
  props.labelStyle
20247
20288
  ];
20248
20289
  });
@@ -20250,24 +20291,25 @@ var VcComponents = (function (exports, vue) {
20250
20291
  const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : form.props.labelWidth;
20251
20292
  return [
20252
20293
  {
20253
- marginLeft: !hasLabel.value && isNest.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
20254
- marginBottom: isNest.value && !isNestLast.value ? `20px` : 0
20294
+ marginLeft: labelPosition.value === "top" || !hasLabel.value && isNested.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
20295
+ marginBottom: isNested.value && !isNestedLast.value ? `20px` : 0
20255
20296
  },
20256
20297
  form.props.contentStyle,
20298
+ isNested.value && form.props.nestedContentStyle,
20257
20299
  props.contentStyle
20258
20300
  ];
20259
20301
  });
20260
20302
  const errorStyle = vue.computed(() => {
20261
- return [form.props.errorStyle, props.errorStyle];
20303
+ return [form.props.errorStyle, isNested.value && form.props.nestedErrorStyle, props.errorStyle];
20262
20304
  });
20263
20305
  const labelClass = vue.computed(() => {
20264
- return [form.props.labelClass, props.labelClass];
20306
+ return [form.props.labelClass, isNested.value && form.props.nestedLabelClass, props.labelClass];
20265
20307
  });
20266
20308
  const contentClass = vue.computed(() => {
20267
- return [form.props.contentClass, props.contentClass];
20309
+ return [form.props.contentClass, isNested.value && form.props.nestedContentClass, props.contentClass];
20268
20310
  });
20269
20311
  const errorClass = vue.computed(() => {
20270
- return [form.props.errorClass, props.errorClass];
20312
+ return [form.props.errorClass, isNested.value && form.props.nestedErrorClass, props.errorClass];
20271
20313
  });
20272
20314
  const isStyleless = vue.computed(() => {
20273
20315
  return props.styleless || form.props.styleless;
@@ -20404,7 +20446,7 @@ var VcComponents = (function (exports, vue) {
20404
20446
  vue.watch(
20405
20447
  () => formItem.fields?.length,
20406
20448
  async (v) => {
20407
- if (!isNest.value || !v) return isNestLast.value = false;
20449
+ if (!isNested.value || !v) return isNestedLast.value = false;
20408
20450
  const fields$ = [...vue.toRaw(formItem.fields)];
20409
20451
  const positions = await Promise.all(fields$.map((item) => item.exposed.getPosition()));
20410
20452
  const sortFields = fields$.toSorted((a, b) => {
@@ -20415,7 +20457,7 @@ var VcComponents = (function (exports, vue) {
20415
20457
  if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
20416
20458
  return aPosition.left - bPosition.left;
20417
20459
  });
20418
- isNestLast.value = sortFields[sortFields.length - 1] === instance;
20460
+ isNestedLast.value = sortFields[sortFields.length - 1] === instance;
20419
20461
  }
20420
20462
  );
20421
20463
  expose({
@@ -20424,9 +20466,9 @@ var VcComponents = (function (exports, vue) {
20424
20466
  getPosition
20425
20467
  });
20426
20468
  return {
20427
- isNest,
20469
+ isNested,
20428
20470
  isStyleless,
20429
- isNestLast,
20471
+ isNestedLast,
20430
20472
  validateMessage,
20431
20473
  classes,
20432
20474
  labelStyle,
@@ -20453,7 +20495,7 @@ var VcComponents = (function (exports, vue) {
20453
20495
  const it = useFormItem(expose);
20454
20496
  const {
20455
20497
  isStyleless,
20456
- isNest,
20498
+ isNested,
20457
20499
  classes,
20458
20500
  labelStyle,
20459
20501
  contentStyle,
@@ -20464,39 +20506,35 @@ var VcComponents = (function (exports, vue) {
20464
20506
  showError,
20465
20507
  validateMessage
20466
20508
  } = it;
20467
- const {
20468
- label,
20469
- labelFor
20470
- } = props;
20471
20509
  const errorColorClass = 'vc-form-item__error';
20472
20510
  return () => {
20473
20511
  if (isStyleless.value) return [slots.default?.(), slots.error?.({
20474
20512
  show: showError.value,
20475
- nest: isNest.value,
20513
+ nested: isNested.value,
20476
20514
  message: validateMessage.value,
20477
20515
  class: [errorColorClass, ...errorClass.value],
20478
20516
  style: errorStyle.value
20479
20517
  })];
20480
20518
  return vue.createVNode("div", {
20481
20519
  "class": ['vc-form-item', classes.value]
20482
- }, [(label || slots.label) && vue.createVNode("div", {
20520
+ }, [(props.label || slots.label) && vue.createVNode("div", {
20483
20521
  "style": labelStyle.value,
20484
20522
  "class": ['vc-form-item__label', ...labelClass.value],
20485
- "for": labelFor
20486
- }, [vue.createVNode("label", null, [label || slots.label?.()])]), vue.createVNode("div", {
20523
+ "for": props.labelFor
20524
+ }, [vue.createVNode("label", null, [props.label || slots.label?.()])]), vue.createVNode("div", {
20487
20525
  "class": "vc-form-item__wrapper"
20488
20526
  }, [vue.createVNode("div", {
20489
20527
  "class": ['vc-form-item__content', ...contentClass.value],
20490
20528
  "style": contentStyle.value
20491
20529
  }, [slots.default?.(), slots.error ? slots.error({
20492
20530
  show: showError.value,
20493
- nest: isNest.value,
20531
+ nest: isNested.value,
20494
20532
  message: validateMessage.value,
20495
20533
  class: [errorColorClass, ...errorClass.value],
20496
20534
  style: errorStyle.value
20497
20535
  }) : vue.createVNode(TransitionFade, null, {
20498
20536
  default: () => [vue.withDirectives(vue.createVNode("div", {
20499
- "class": ['vc-form-item__tip', isNest.value ? 'is-nest' : '', errorColorClass, ...errorClass.value],
20537
+ "class": ['vc-form-item__tip', isNested.value ? 'is-nested' : '', errorColorClass, ...errorClass.value],
20500
20538
  "style": [errorStyle.value]
20501
20539
  }, [validateMessage.value]), [[vue.vShow, showError.value]])]
20502
20540
  })])])]);
@@ -20567,41 +20605,36 @@ var VcComponents = (function (exports, vue) {
20567
20605
  labelClass,
20568
20606
  contentClass,
20569
20607
  errorClass,
20570
- isNest,
20608
+ isNested,
20571
20609
  showError,
20572
20610
  validateMessage
20573
20611
  } = it;
20574
- const {
20575
- label,
20576
- labelFor,
20577
- showMessage
20578
- } = props;
20579
20612
  const errorColorClass = 'vcm-form-item__error';
20580
20613
  return () => {
20581
20614
  if (isStyleless.value) return [slots.default?.(), slots.error?.({
20582
20615
  show: showError.value,
20583
- nest: isNest.value,
20616
+ nested: isNested.value,
20584
20617
  message: validateMessage.value,
20585
20618
  class: [errorColorClass, ...errorClass.value],
20586
20619
  style: errorStyle.value
20587
20620
  })];
20588
20621
  return vue.createVNode("div", {
20589
20622
  "style": {
20590
- paddingLeft: `${isNest.value ? 0 : props.indent}px`
20623
+ paddingLeft: `${isNested.value ? 0 : props.indent}px`
20591
20624
  },
20592
20625
  "class": [classes.value, 'vcm-form-item']
20593
20626
  }, [vue.createVNode("div", {
20594
20627
  "class": "vcm-form-item__wrapper"
20595
20628
  }, [(props.label || slots.label) && vue.createVNode("label", {
20596
- "for": labelFor,
20629
+ "for": props.labelFor,
20597
20630
  "style": labelStyle.value,
20598
20631
  "class": ['vcm-form-item__label', ...labelClass.value]
20599
- }, [label || slots.label?.()]), vue.createVNode("div", {
20632
+ }, [props.label || slots.label?.()]), vue.createVNode("div", {
20600
20633
  "style": contentStyle.value,
20601
20634
  "class": ['vcm-form-item__content', ...contentClass.value]
20602
- }, [slots.default?.(), showMessage && showError.value && vue.createVNode("div", {
20635
+ }, [slots.default?.(), props.showMessage && showError.value && vue.createVNode("div", {
20603
20636
  "class": [{
20604
- 'is-nest': isNest.value
20637
+ 'is-nested': isNested.value
20605
20638
  }, errorColorClass, ...errorClass.value],
20606
20639
  "style": errorStyle.value
20607
20640
  }, [slots.error ? slots.error({
@@ -21128,7 +21161,7 @@ var VcComponents = (function (exports, vue) {
21128
21161
  } else if (typeof wrapper === 'string') {
21129
21162
  scroller.value = document.querySelector(wrapper);
21130
21163
  } else {
21131
- scroller.value = getScroller(instance.vnode.el);
21164
+ scroller.value = getScroller$1(instance.vnode.el);
21132
21165
  }
21133
21166
  };
21134
21167
  const initPlaceholder = () => {
@@ -23264,13 +23297,13 @@ var VcComponents = (function (exports, vue) {
23264
23297
  "readonly": true,
23265
23298
  "placeholder": its.value.attrs?.placeholder || '请选择'
23266
23299
  }, {
23267
- prepend: () => {
23268
- if (slots.prepend) return slots.prepend?.();
23269
- if (!props.label) return null;
23270
- return vue.createVNode("span", {
23300
+ prepend: slots.prepend || props.label ? () => {
23301
+ slots.prepend ? slots.prepend() : vue.createVNode("div", {
23302
+ "class": "vc-select__prepend"
23303
+ }, [vue.createVNode("span", {
23271
23304
  "class": "vc-select__label"
23272
- }, [props.label]);
23273
- },
23305
+ }, [props.label])]);
23306
+ } : null,
23274
23307
  content: multiple.value && currentValue.value && currentValue.value.length > 0 ? () => {
23275
23308
  return vue.createVNode("div", {
23276
23309
  "class": [classes.value, 'vc-select__tags']
@@ -29026,10 +29059,13 @@ var VcComponents = (function (exports, vue) {
29026
29059
  barStyle: [Object, String],
29027
29060
  contentStyle: [Object, String],
29028
29061
  barClass: [Object, String],
29029
- contentClass: [Object, String]
29062
+ contentClass: [Object, String],
29063
+ affixable: Boolean,
29064
+ affixOptions: Object
29030
29065
  };
29031
29066
 
29032
29067
  const useTabs = (options = {}) => {
29068
+ const affix = vue.inject("vc-affix", null);
29033
29069
  const instance = vue.getCurrentInstance();
29034
29070
  const { props, emit } = instance;
29035
29071
  const tabsId = vue.ref(getUid("tabs"));
@@ -29071,10 +29107,56 @@ var VcComponents = (function (exports, vue) {
29071
29107
  [`is-${props.theme}`]: !!props.theme
29072
29108
  };
29073
29109
  });
29110
+ const hasAnchor = vue.computed(() => {
29111
+ return list.value.some((item) => !!item.anchor);
29112
+ });
29074
29113
  const refresh = () => {
29075
29114
  options?.refreshAfloat?.();
29076
29115
  };
29077
- 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) => {
29078
29160
  if (timer.value) return;
29079
29161
  timer.value = setTimeout(() => timer.value = null, 300);
29080
29162
  const nav = list.value[index];
@@ -29083,7 +29165,7 @@ var VcComponents = (function (exports, vue) {
29083
29165
  emit("update:modelValue", currentValue.value);
29084
29166
  emit("change", currentValue.value);
29085
29167
  emit("click", currentValue.value);
29086
- nav.anchor && document.querySelector(nav.anchor)?.scrollIntoView?.({ behavior: "smooth" });
29168
+ scrollTo && scrollToAnchor(nav.anchor);
29087
29169
  };
29088
29170
  const handleResize = () => {
29089
29171
  if (instance.isUnmounted) return;
@@ -29093,10 +29175,13 @@ var VcComponents = (function (exports, vue) {
29093
29175
  vue.onMounted(() => {
29094
29176
  Resize.on(options.wrapper.value, handleResize);
29095
29177
  options.scrollToActive && vue.nextTick(options.scrollToActive);
29178
+ affix?.onScroll?.(handleAffixScroll);
29096
29179
  });
29097
29180
  vue.onBeforeUnmount(() => {
29098
29181
  Resize.off(options.wrapper.value, handleResize);
29099
29182
  timer.value && clearTimeout(timer.value);
29183
+ affix?.offScroll?.(handleAffixScroll);
29184
+ scrollToAnchorTimer && clearTimeout(scrollToAnchorTimer);
29100
29185
  });
29101
29186
  const add = (item, setValue) => {
29102
29187
  if (!item) return;