@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.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { reactive, defineComponent, createVNode, inject, shallowRef, ref, computed, onMounted, onBeforeUnmount, watch, getCurrentInstance, TransitionGroup, Transition as Transition$1, h, provide, nextTick, mergeProps, withModifiers, createApp, Fragment as Fragment$1, Teleport, onUnmounted, withDirectives, vShow, isVNode, onBeforeMount, createTextVNode, toRaw, onUpdated, resolveComponent, useAttrs as useAttrs$1 } from 'vue';
1
+ import { reactive, defineComponent, createVNode, inject, shallowRef, ref, computed, onMounted, onBeforeUnmount, provide, nextTick, watch, getCurrentInstance, TransitionGroup, Transition as Transition$1, h, mergeProps, withModifiers, createApp, Fragment as Fragment$1, Teleport, onUnmounted, withDirectives, vShow, isVNode, onBeforeMount, createTextVNode, toRaw, onUpdated, resolveComponent, useAttrs as useAttrs$1 } from 'vue';
2
2
  import * as $ from '@deot/helper-dom';
3
- import { getScroller, composedPath, scrollIntoView, prefixStyle, getStyle, removeClass, addClass, hasClass } from '@deot/helper-dom';
3
+ import { getScroller as getScroller$1, composedPath, scrollIntoView, prefixStyle, getStyle, removeClass, addClass, hasClass } from '@deot/helper-dom';
4
4
  import * as Utils from '@deot/helper-utils';
5
5
  import { raf, getUid, preZero, getPropByPath, throttle as throttle$1, hasOwn } from '@deot/helper-utils';
6
6
  import { debounce, cloneDeep, pick, isEqualWith, startCase, throttle, concat, max, merge, isEmpty as isEmpty$1, kebabCase, difference } from 'lodash-es';
@@ -106,6 +106,10 @@ const ActionSheet = /* @__PURE__ */ defineComponent({
106
106
  const MActionSheet = ActionSheet;
107
107
 
108
108
  const props$1s = {
109
+ modelValue: {
110
+ type: Boolean,
111
+ default: false
112
+ },
109
113
  zIndex: {
110
114
  type: [Number, String],
111
115
  default: 1
@@ -133,16 +137,45 @@ const props$1s = {
133
137
  }
134
138
  };
135
139
 
140
+ let scrollBarWidth;
141
+ const getScrollBarWidth = () => {
142
+ if (scrollBarWidth !== void 0) return scrollBarWidth;
143
+ const outer = document.createElement("div");
144
+ outer.className = "vc-scrollbar__wrap";
145
+ outer.style.visibility = "hidden";
146
+ outer.style.width = "100px";
147
+ outer.style.position = "absolute";
148
+ outer.style.top = "-9999px";
149
+ document.body.appendChild(outer);
150
+ const widthNoScroll = outer.offsetWidth;
151
+ outer.style.overflow = "scroll";
152
+ const inner = document.createElement("div");
153
+ inner.style.width = "100%";
154
+ outer.appendChild(inner);
155
+ const widthWithScroll = inner.offsetWidth;
156
+ outer.parentNode?.removeChild?.(outer);
157
+ scrollBarWidth = widthNoScroll - widthWithScroll;
158
+ return scrollBarWidth;
159
+ };
160
+ const SCROLLER_WHEEL_REG = /vc-scroller-wheel/;
161
+ const getScroller = (el) => {
162
+ return getScroller$1(el, { className: SCROLLER_WHEEL_REG });
163
+ };
164
+ const isWheel = (el) => {
165
+ return SCROLLER_WHEEL_REG.test(el?.className || "");
166
+ };
167
+
136
168
  /** @jsxImportSource vue */
137
169
 
138
170
  const COMPONENT_NAME$27 = 'vc-affix';
139
- const SCROLLER_WHEEL_REG = /vc-scroller-wheel/;
140
171
  const Affix = /* @__PURE__ */ defineComponent({
141
172
  name: COMPONENT_NAME$27,
173
+ emits: ['update:modelValue'],
142
174
  props: props$1s,
143
175
  setup(props, {
144
176
  slots,
145
- expose
177
+ expose,
178
+ emit
146
179
  }) {
147
180
  const scrollerInstance = inject('vc-scroller', null);
148
181
  const scroller = shallowRef(); // 当前元素所在的滚动容器
@@ -158,9 +191,7 @@ const Affix = /* @__PURE__ */ defineComponent({
158
191
  const isActive = ref(false);
159
192
  const transformY = ref(0);
160
193
  const windowHeight = ref(window.innerHeight);
161
- const isVcScrollerWheel = computed(() => {
162
- return SCROLLER_WHEEL_REG.test(scroller.value?.className || '');
163
- });
194
+ const isVcScrollerWheel = computed(() => isWheel(scroller.value));
164
195
  const currentStyle = computed(() => {
165
196
  if (!isActive.value) return {};
166
197
  return {
@@ -181,7 +212,8 @@ const Affix = /* @__PURE__ */ defineComponent({
181
212
  };
182
213
  });
183
214
  const setCurrentRect = () => {
184
- const rect = current.value.getBoundingClientRect();
215
+ const rect = current.value?.getBoundingClientRect?.();
216
+ if (!rect) return;
185
217
  Object.assign(currentRect, {
186
218
  top: rect.top,
187
219
  bottom: rect.bottom,
@@ -208,7 +240,7 @@ const Affix = /* @__PURE__ */ defineComponent({
208
240
  transformY.value = Math.min(containerRect.bottom - currentHeightOffset, 0) + transformOffsetY;
209
241
  } else {
210
242
  isActive.value = currentRect.bottom - containerRect.top >= containerRect.height - props.offset;
211
- transformY.value = Math.max(containerRect.height - containerRect.top - currentHeightOffset, 0) + transformOffsetY;
243
+ transformY.value = transformOffsetY;
212
244
  }
213
245
  };
214
246
  const setFixedStatus = () => {
@@ -235,36 +267,58 @@ const Affix = /* @__PURE__ */ defineComponent({
235
267
  }
236
268
  }
237
269
  };
270
+ const offScroll = handler => {
271
+ if (isVcScrollerWheel.value) {
272
+ scrollerInstance?.off(handler);
273
+ } else {
274
+ scroller.value?.removeEventListener('scroll', handler);
275
+ }
276
+ };
277
+ const onScroll = (handler, options) => {
278
+ // nextTick目的在与onMounted后执行
279
+ nextTick(() => {
280
+ if (isVcScrollerWheel.value) {
281
+ scrollerInstance?.on(handler);
282
+ } else {
283
+ scroller.value?.addEventListener('scroll', handler);
284
+ }
285
+ options?.first && handler();
286
+ });
287
+ return () => offScroll(handler);
288
+ };
238
289
  const refresh = () => {
290
+ if (props.disabled) return;
239
291
  setCurrentRect();
240
292
  scroller.value instanceof Window || props.fixed ? setFixedStatus() : setAbsoluteStatus();
293
+ emit('update:modelValue', isActive.value);
241
294
  };
242
295
  onMounted(() => {
243
296
  if (typeof props.target === 'string') {
244
297
  base.value = document.querySelector(props.target) ?? void 0;
245
298
  }
246
299
  !base.value && (base.value = document.documentElement);
247
- scroller.value = getScroller(current.value, {
248
- className: SCROLLER_WHEEL_REG
300
+ scroller.value = getScroller(current.value);
301
+ onScroll(refresh, {
302
+ first: true
249
303
  });
250
- if (isVcScrollerWheel.value) {
251
- scrollerInstance?.on(refresh);
252
- } else {
253
- scroller.value?.addEventListener('scroll', refresh);
254
- }
255
- refresh();
256
- });
257
- onBeforeUnmount(() => {
258
- if (isVcScrollerWheel.value) {
259
- scrollerInstance?.off(refresh);
260
- } else {
261
- scroller.value?.removeEventListener('scroll', refresh);
262
- }
263
304
  });
305
+ onBeforeUnmount(() => offScroll(refresh));
264
306
  expose({
265
- refresh
307
+ refresh,
308
+ onScroll,
309
+ offScroll
310
+ });
311
+ provide('vc-affix', {
312
+ props,
313
+ isActive,
314
+ refresh,
315
+ onScroll,
316
+ offScroll
266
317
  });
267
318
  return () => {
319
+ if (props.disabled) return slots?.default?.({
320
+ active: false
321
+ });
268
322
  return createVNode("div", {
269
323
  "ref": current,
270
324
  "class": "vc-affix",
@@ -8841,27 +8895,6 @@ const props$T = {
8841
8895
  }
8842
8896
  };
8843
8897
 
8844
- let scrollBarWidth;
8845
- const getScrollBarWidth = () => {
8846
- if (scrollBarWidth !== void 0) return scrollBarWidth;
8847
- const outer = document.createElement("div");
8848
- outer.className = "vc-scrollbar__wrap";
8849
- outer.style.visibility = "hidden";
8850
- outer.style.width = "100px";
8851
- outer.style.position = "absolute";
8852
- outer.style.top = "-9999px";
8853
- document.body.appendChild(outer);
8854
- const widthNoScroll = outer.offsetWidth;
8855
- outer.style.overflow = "scroll";
8856
- const inner = document.createElement("div");
8857
- inner.style.width = "100%";
8858
- outer.appendChild(inner);
8859
- const widthWithScroll = inner.offsetWidth;
8860
- outer.parentNode?.removeChild?.(outer);
8861
- scrollBarWidth = widthNoScroll - widthWithScroll;
8862
- return scrollBarWidth;
8863
- };
8864
-
8865
8898
  const barKeys$1 = [
8866
8899
  "always",
8867
8900
  "thumbMinSize",
@@ -11433,7 +11466,14 @@ const props$L = {
11433
11466
  labelStyle: [Object, String],
11434
11467
  labelClass: [Object, String],
11435
11468
  errorStyle: [Object, String],
11436
- errorClass: [Object, String]
11469
+ errorClass: [Object, String],
11470
+ // 给nestFormItem统一注入
11471
+ nestedContentStyle: [Object, String],
11472
+ nestedContentClass: [Object, String],
11473
+ nestedLabelStyle: [Object, String],
11474
+ nestedLabelClass: [Object, String],
11475
+ nestedErrorStyle: [Object, String],
11476
+ nestedErrorClass: [Object, String]
11437
11477
  };
11438
11478
 
11439
11479
  const useForm = (expose, options = {}) => {
@@ -11653,31 +11693,32 @@ const useFormItem = (expose) => {
11653
11693
  });
11654
11694
  const classes = computed(() => {
11655
11695
  return {
11656
- "is-require": isRequired.value && props.asterisk,
11696
+ "is-required": isRequired.value && props.asterisk,
11657
11697
  "is-error": validateState.value === "error",
11658
11698
  "is-validating": validateState.value === "validating",
11659
11699
  "is-inline": form.props.inline,
11660
- "is-nest": isNest.value,
11700
+ "is-nested": isNested.value,
11661
11701
  "is-alone": !props.showMessage,
11662
11702
  // 用于单独去除form-item的默认margin_bottom
11663
11703
  [`is-${labelPosition.value}`]: true
11664
11704
  };
11665
11705
  });
11666
- const isNest = computed(() => {
11706
+ const isNested = computed(() => {
11667
11707
  return !!formItem.change;
11668
11708
  });
11669
- const isNestLast = ref(false);
11709
+ const isNestedLast = ref(false);
11670
11710
  const hasLabel = computed(() => {
11671
11711
  return !!props.label || slots.label;
11672
11712
  });
11673
11713
  const labelStyle = computed(() => {
11674
- const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNest.value ? 0 : form.props.labelWidth;
11714
+ const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : isNested.value ? 0 : form.props.labelWidth;
11675
11715
  return [
11676
11716
  {
11677
11717
  width: labelPosition.value !== "top" && labelWidth && labelWidth > 0 ? `${labelWidth}px` : "auto",
11678
11718
  textAlign: labelPosition.value === "top" ? "left" : labelPosition.value
11679
11719
  },
11680
11720
  form.props.labelStyle,
11721
+ isNested.value && form.props.nestedLabelStyle,
11681
11722
  props.labelStyle
11682
11723
  ];
11683
11724
  });
@@ -11685,24 +11726,25 @@ const useFormItem = (expose) => {
11685
11726
  const labelWidth = props.labelWidth === 0 || props.labelWidth ? props.labelWidth : form.props.labelWidth;
11686
11727
  return [
11687
11728
  {
11688
- marginLeft: !hasLabel.value && isNest.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
11689
- marginBottom: isNest.value && !isNestLast.value ? `20px` : 0
11729
+ marginLeft: labelPosition.value === "top" || !hasLabel.value && isNested.value ? 0 : labelWidth && labelWidth > 0 ? `${labelWidth}px` : "unset",
11730
+ marginBottom: isNested.value && !isNestedLast.value ? `20px` : 0
11690
11731
  },
11691
11732
  form.props.contentStyle,
11733
+ isNested.value && form.props.nestedContentStyle,
11692
11734
  props.contentStyle
11693
11735
  ];
11694
11736
  });
11695
11737
  const errorStyle = computed(() => {
11696
- return [form.props.errorStyle, props.errorStyle];
11738
+ return [form.props.errorStyle, isNested.value && form.props.nestedErrorStyle, props.errorStyle];
11697
11739
  });
11698
11740
  const labelClass = computed(() => {
11699
- return [form.props.labelClass, props.labelClass];
11741
+ return [form.props.labelClass, isNested.value && form.props.nestedLabelClass, props.labelClass];
11700
11742
  });
11701
11743
  const contentClass = computed(() => {
11702
- return [form.props.contentClass, props.contentClass];
11744
+ return [form.props.contentClass, isNested.value && form.props.nestedContentClass, props.contentClass];
11703
11745
  });
11704
11746
  const errorClass = computed(() => {
11705
- return [form.props.errorClass, props.errorClass];
11747
+ return [form.props.errorClass, isNested.value && form.props.nestedErrorClass, props.errorClass];
11706
11748
  });
11707
11749
  const isStyleless = computed(() => {
11708
11750
  return props.styleless || form.props.styleless;
@@ -11839,7 +11881,7 @@ const useFormItem = (expose) => {
11839
11881
  watch(
11840
11882
  () => formItem.fields?.length,
11841
11883
  async (v) => {
11842
- if (!isNest.value || !v) return isNestLast.value = false;
11884
+ if (!isNested.value || !v) return isNestedLast.value = false;
11843
11885
  const fields$ = [...toRaw(formItem.fields)];
11844
11886
  const positions = await Promise.all(fields$.map((item) => item.exposed.getPosition()));
11845
11887
  const sortFields = fields$.toSorted((a, b) => {
@@ -11850,7 +11892,7 @@ const useFormItem = (expose) => {
11850
11892
  if (aPosition.top != bPosition.top) return aPosition.top - bPosition.top;
11851
11893
  return aPosition.left - bPosition.left;
11852
11894
  });
11853
- isNestLast.value = sortFields[sortFields.length - 1] === instance;
11895
+ isNestedLast.value = sortFields[sortFields.length - 1] === instance;
11854
11896
  }
11855
11897
  );
11856
11898
  expose({
@@ -11859,9 +11901,9 @@ const useFormItem = (expose) => {
11859
11901
  getPosition
11860
11902
  });
11861
11903
  return {
11862
- isNest,
11904
+ isNested,
11863
11905
  isStyleless,
11864
- isNestLast,
11906
+ isNestedLast,
11865
11907
  validateMessage,
11866
11908
  classes,
11867
11909
  labelStyle,
@@ -11888,7 +11930,7 @@ const FormItem = /* @__PURE__ */ defineComponent({
11888
11930
  const it = useFormItem(expose);
11889
11931
  const {
11890
11932
  isStyleless,
11891
- isNest,
11933
+ isNested,
11892
11934
  classes,
11893
11935
  labelStyle,
11894
11936
  contentStyle,
@@ -11899,39 +11941,35 @@ const FormItem = /* @__PURE__ */ defineComponent({
11899
11941
  showError,
11900
11942
  validateMessage
11901
11943
  } = it;
11902
- const {
11903
- label,
11904
- labelFor
11905
- } = props;
11906
11944
  const errorColorClass = 'vc-form-item__error';
11907
11945
  return () => {
11908
11946
  if (isStyleless.value) return [slots.default?.(), slots.error?.({
11909
11947
  show: showError.value,
11910
- nest: isNest.value,
11948
+ nested: isNested.value,
11911
11949
  message: validateMessage.value,
11912
11950
  class: [errorColorClass, ...errorClass.value],
11913
11951
  style: errorStyle.value
11914
11952
  })];
11915
11953
  return createVNode("div", {
11916
11954
  "class": ['vc-form-item', classes.value]
11917
- }, [(label || slots.label) && createVNode("div", {
11955
+ }, [(props.label || slots.label) && createVNode("div", {
11918
11956
  "style": labelStyle.value,
11919
11957
  "class": ['vc-form-item__label', ...labelClass.value],
11920
- "for": labelFor
11921
- }, [createVNode("label", null, [label || slots.label?.()])]), createVNode("div", {
11958
+ "for": props.labelFor
11959
+ }, [createVNode("label", null, [props.label || slots.label?.()])]), createVNode("div", {
11922
11960
  "class": "vc-form-item__wrapper"
11923
11961
  }, [createVNode("div", {
11924
11962
  "class": ['vc-form-item__content', ...contentClass.value],
11925
11963
  "style": contentStyle.value
11926
11964
  }, [slots.default?.(), slots.error ? slots.error({
11927
11965
  show: showError.value,
11928
- nest: isNest.value,
11966
+ nest: isNested.value,
11929
11967
  message: validateMessage.value,
11930
11968
  class: [errorColorClass, ...errorClass.value],
11931
11969
  style: errorStyle.value
11932
11970
  }) : createVNode(TransitionFade, null, {
11933
11971
  default: () => [withDirectives(createVNode("div", {
11934
- "class": ['vc-form-item__tip', isNest.value ? 'is-nest' : '', errorColorClass, ...errorClass.value],
11972
+ "class": ['vc-form-item__tip', isNested.value ? 'is-nested' : '', errorColorClass, ...errorClass.value],
11935
11973
  "style": [errorStyle.value]
11936
11974
  }, [validateMessage.value]), [[vShow, showError.value]])]
11937
11975
  })])])]);
@@ -12002,41 +12040,36 @@ const MFormItem = /* @__PURE__ */ defineComponent({
12002
12040
  labelClass,
12003
12041
  contentClass,
12004
12042
  errorClass,
12005
- isNest,
12043
+ isNested,
12006
12044
  showError,
12007
12045
  validateMessage
12008
12046
  } = it;
12009
- const {
12010
- label,
12011
- labelFor,
12012
- showMessage
12013
- } = props;
12014
12047
  const errorColorClass = 'vcm-form-item__error';
12015
12048
  return () => {
12016
12049
  if (isStyleless.value) return [slots.default?.(), slots.error?.({
12017
12050
  show: showError.value,
12018
- nest: isNest.value,
12051
+ nested: isNested.value,
12019
12052
  message: validateMessage.value,
12020
12053
  class: [errorColorClass, ...errorClass.value],
12021
12054
  style: errorStyle.value
12022
12055
  })];
12023
12056
  return createVNode("div", {
12024
12057
  "style": {
12025
- paddingLeft: `${isNest.value ? 0 : props.indent}px`
12058
+ paddingLeft: `${isNested.value ? 0 : props.indent}px`
12026
12059
  },
12027
12060
  "class": [classes.value, 'vcm-form-item']
12028
12061
  }, [createVNode("div", {
12029
12062
  "class": "vcm-form-item__wrapper"
12030
12063
  }, [(props.label || slots.label) && createVNode("label", {
12031
- "for": labelFor,
12064
+ "for": props.labelFor,
12032
12065
  "style": labelStyle.value,
12033
12066
  "class": ['vcm-form-item__label', ...labelClass.value]
12034
- }, [label || slots.label?.()]), createVNode("div", {
12067
+ }, [props.label || slots.label?.()]), createVNode("div", {
12035
12068
  "style": contentStyle.value,
12036
12069
  "class": ['vcm-form-item__content', ...contentClass.value]
12037
- }, [slots.default?.(), showMessage && showError.value && createVNode("div", {
12070
+ }, [slots.default?.(), props.showMessage && showError.value && createVNode("div", {
12038
12071
  "class": [{
12039
- 'is-nest': isNest.value
12072
+ 'is-nested': isNested.value
12040
12073
  }, errorColorClass, ...errorClass.value],
12041
12074
  "style": errorStyle.value
12042
12075
  }, [slots.error ? slots.error({
@@ -14325,13 +14358,13 @@ const Select = /* @__PURE__ */ defineComponent({
14325
14358
  "readonly": true,
14326
14359
  "placeholder": its.value.attrs?.placeholder || '请选择'
14327
14360
  }, {
14328
- prepend: () => {
14329
- if (slots.prepend) return slots.prepend?.();
14330
- if (!props.label) return null;
14331
- return createVNode("span", {
14361
+ prepend: slots.prepend || props.label ? () => {
14362
+ slots.prepend ? slots.prepend() : createVNode("div", {
14363
+ "class": "vc-select__prepend"
14364
+ }, [createVNode("span", {
14332
14365
  "class": "vc-select__label"
14333
- }, [props.label]);
14334
- },
14366
+ }, [props.label])]);
14367
+ } : null,
14335
14368
  content: multiple.value && currentValue.value && currentValue.value.length > 0 ? () => {
14336
14369
  return createVNode("div", {
14337
14370
  "class": [classes.value, 'vc-select__tags']
@@ -19973,10 +20006,13 @@ const props$c = {
19973
20006
  barStyle: [Object, String],
19974
20007
  contentStyle: [Object, String],
19975
20008
  barClass: [Object, String],
19976
- contentClass: [Object, String]
20009
+ contentClass: [Object, String],
20010
+ affixable: Boolean,
20011
+ affixOptions: Object
19977
20012
  };
19978
20013
 
19979
20014
  const useTabs = (options = {}) => {
20015
+ const affix = inject("vc-affix", null);
19980
20016
  const instance = getCurrentInstance();
19981
20017
  const { props, emit } = instance;
19982
20018
  const tabsId = ref(getUid("tabs"));
@@ -20018,10 +20054,56 @@ const useTabs = (options = {}) => {
20018
20054
  [`is-${props.theme}`]: !!props.theme
20019
20055
  };
20020
20056
  });
20057
+ const hasAnchor = computed(() => {
20058
+ return list.value.some((item) => !!item.anchor);
20059
+ });
20021
20060
  const refresh = () => {
20022
20061
  options?.refreshAfloat?.();
20023
20062
  };
20024
- const handleChange = (index) => {
20063
+ let scrollToAnchorTimer;
20064
+ const scrollToAnchor = (anchor) => {
20065
+ if (!anchor) return;
20066
+ const el = document.querySelector(anchor);
20067
+ if (!el) return;
20068
+ const scroller = getScroller(instance.vnode.el);
20069
+ scrollIntoView(scroller, {
20070
+ duration: 250,
20071
+ from: scroller.scrollTop,
20072
+ 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)
20073
+ });
20074
+ scrollToAnchorTimer && clearTimeout(scrollToAnchorTimer);
20075
+ scrollToAnchorTimer = setTimeout(() => scrollToAnchorTimer = null, 300);
20076
+ };
20077
+ const handleAffixScroll = () => {
20078
+ if (!hasAnchor.value || scrollToAnchorTimer) return;
20079
+ const scroller = getScroller(instance.vnode.el);
20080
+ const scrollTop = scroller?.scrollTop;
20081
+ if (typeof scrollTop !== "number") return;
20082
+ for (let i = 0; i < list.value.length; i++) {
20083
+ const nav = list.value[i];
20084
+ const anchor = nav.anchor;
20085
+ if (!anchor) continue;
20086
+ const el = document.querySelector(anchor);
20087
+ if (!el) continue;
20088
+ const elTop = el.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop;
20089
+ const nextNav = list.value[i + 1];
20090
+ let nextElTop;
20091
+ if (nextNav && nextNav.anchor) {
20092
+ const nextEl = document.querySelector(nextNav.anchor);
20093
+ if (nextEl) {
20094
+ nextElTop = nextEl.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop;
20095
+ }
20096
+ }
20097
+ const allowDistance = 2;
20098
+ if (scrollTop >= elTop - allowDistance && (typeof nextElTop === "undefined" || scrollTop < nextElTop - allowDistance)) {
20099
+ if (getTabIndex(currentValue.value) !== i) {
20100
+ handleChange(i, false);
20101
+ }
20102
+ break;
20103
+ }
20104
+ }
20105
+ };
20106
+ const handleChange = (index, scrollTo = true) => {
20025
20107
  if (timer.value) return;
20026
20108
  timer.value = setTimeout(() => timer.value = null, 300);
20027
20109
  const nav = list.value[index];
@@ -20030,7 +20112,7 @@ const useTabs = (options = {}) => {
20030
20112
  emit("update:modelValue", currentValue.value);
20031
20113
  emit("change", currentValue.value);
20032
20114
  emit("click", currentValue.value);
20033
- nav.anchor && document.querySelector(nav.anchor)?.scrollIntoView?.({ behavior: "smooth" });
20115
+ scrollTo && scrollToAnchor(nav.anchor);
20034
20116
  };
20035
20117
  const handleResize = () => {
20036
20118
  if (instance.isUnmounted) return;
@@ -20040,10 +20122,13 @@ const useTabs = (options = {}) => {
20040
20122
  onMounted(() => {
20041
20123
  Resize.on(options.wrapper.value, handleResize);
20042
20124
  options.scrollToActive && nextTick(options.scrollToActive);
20125
+ affix?.onScroll?.(handleAffixScroll);
20043
20126
  });
20044
20127
  onBeforeUnmount(() => {
20045
20128
  Resize.off(options.wrapper.value, handleResize);
20046
20129
  timer.value && clearTimeout(timer.value);
20130
+ affix?.offScroll?.(handleAffixScroll);
20131
+ scrollToAnchorTimer && clearTimeout(scrollToAnchorTimer);
20047
20132
  });
20048
20133
  const add = (item, setValue) => {
20049
20134
  if (!item) return;