@deot/vc-components 1.0.47 → 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",
@@ -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",
@@ -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;
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",
@@ -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;