@vuetify/nightly 3.8.2-master.2025-04-27 → 3.8.3-dev.2025-04-29

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +13 -32
  2. package/dist/json/attributes.json +2092 -2084
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +148 -148
  5. package/dist/json/tags.json +2 -0
  6. package/dist/json/web-types.json +3854 -3834
  7. package/dist/vuetify-labs.cjs +146 -36
  8. package/dist/vuetify-labs.css +3420 -3397
  9. package/dist/vuetify-labs.d.ts +101 -64
  10. package/dist/vuetify-labs.esm.js +147 -37
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +146 -36
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +146 -36
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +3284 -3261
  17. package/dist/vuetify.d.ts +101 -64
  18. package/dist/vuetify.esm.js +147 -37
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +146 -36
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1201 -1188
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  26. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  27. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  28. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  29. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  30. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  31. package/lib/components/VInput/VInput.d.ts +1 -1
  32. package/lib/components/VOverlay/VOverlay.css +1 -1
  33. package/lib/components/VOverlay/_variables.scss +1 -1
  34. package/lib/components/VOverlay/locationStrategies.d.ts +4 -0
  35. package/lib/components/VOverlay/locationStrategies.js +23 -3
  36. package/lib/components/VOverlay/locationStrategies.js.map +1 -1
  37. package/lib/composables/calendar.d.ts +1 -0
  38. package/lib/composables/calendar.js.map +1 -1
  39. package/lib/composables/defaults.js +6 -3
  40. package/lib/composables/defaults.js.map +1 -1
  41. package/lib/composables/theme.d.ts +6 -1
  42. package/lib/composables/theme.js +94 -26
  43. package/lib/composables/theme.js.map +1 -1
  44. package/lib/composables/virtual.js +6 -1
  45. package/lib/composables/virtual.js.map +1 -1
  46. package/lib/entry-bundler.js +1 -1
  47. package/lib/entry-bundler.js.map +1 -1
  48. package/lib/framework.d.ts +63 -54
  49. package/lib/framework.js +1 -1
  50. package/lib/framework.js.map +1 -1
  51. package/lib/util/globals.d.ts +1 -0
  52. package/lib/util/globals.js +1 -0
  53. package/lib/util/globals.js.map +1 -1
  54. package/lib/util/helpers.d.ts +2 -0
  55. package/lib/util/helpers.js +7 -0
  56. package/lib/util/helpers.js.map +1 -1
  57. package/package.json +3 -2
@@ -1,15 +1,16 @@
1
1
  /*!
2
- * Vuetify v3.8.2-master.2025-04-27
2
+ * Vuetify v3.8.3-dev.2025-04-29
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
- import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, camelize, createVNode, mergeProps, toValue, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, TransitionGroup, Transition, toRefs, isRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
7
+ import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, camelize, createVNode, mergeProps, toValue, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, TransitionGroup, Transition, toRefs, isRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
8
8
 
9
9
  const IN_BROWSER = typeof window !== 'undefined';
10
10
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
11
11
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
12
12
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
13
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
13
14
 
14
15
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
15
16
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -335,6 +336,9 @@ class CircularBuffer {
335
336
  _classPrivateFieldInitSpec(this, _pointer, 0);
336
337
  this.size = size;
337
338
  }
339
+ get isFull() {
340
+ return _classPrivateFieldGet(_arr, this).length === this.size;
341
+ }
338
342
  push(val) {
339
343
  _classPrivateFieldGet(_arr, this)[_classPrivateFieldGet(_pointer, this)] = val;
340
344
  _classPrivateFieldSet(_pointer, this, (_classPrivateFieldGet(_pointer, this) + 1) % this.size);
@@ -342,6 +346,10 @@ class CircularBuffer {
342
346
  values() {
343
347
  return _classPrivateFieldGet(_arr, this).slice(_classPrivateFieldGet(_pointer, this)).concat(_classPrivateFieldGet(_arr, this).slice(0, _classPrivateFieldGet(_pointer, this)));
344
348
  }
349
+ clear() {
350
+ _classPrivateFieldGet(_arr, this).length = 0;
351
+ _classPrivateFieldSet(_pointer, this, 0);
352
+ }
345
353
  }
346
354
  function getEventCoordinates(e) {
347
355
  if ('touches' in e) {
@@ -1332,7 +1340,7 @@ function provideDefaults(defaults, options) {
1332
1340
  return newDefaults;
1333
1341
  }
1334
1342
  function propIsDefined(vnode, prop) {
1335
- return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
1343
+ return vnode.props && (typeof vnode.props[prop] !== 'undefined' || typeof vnode.props[toKebabCase(prop)] !== 'undefined');
1336
1344
  }
1337
1345
  function internalUseDefaults() {
1338
1346
  let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -1349,9 +1357,12 @@ function internalUseDefaults() {
1349
1357
  const propValue = Reflect.get(target, prop);
1350
1358
  if (prop === 'class' || prop === 'style') {
1351
1359
  return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
1352
- } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
1353
- return componentDefaults.value?.[prop] !== undefined ? componentDefaults.value?.[prop] : defaults.value?.global?.[prop] !== undefined ? defaults.value?.global?.[prop] : propValue;
1354
1360
  }
1361
+ if (propIsDefined(vm.vnode, prop)) return propValue;
1362
+ const _componentDefault = componentDefaults.value?.[prop];
1363
+ if (_componentDefault !== undefined) return _componentDefault;
1364
+ const _globalDefault = defaults.value?.global?.[prop];
1365
+ if (_globalDefault !== undefined) return _globalDefault;
1355
1366
  return propValue;
1356
1367
  }
1357
1368
  });
@@ -2771,6 +2782,7 @@ const makeThemeProps = propsFactory({
2771
2782
  function genDefaults$1() {
2772
2783
  return {
2773
2784
  defaultTheme: 'light',
2785
+ prefix: 'v-',
2774
2786
  variations: {
2775
2787
  colors: [],
2776
2788
  lighten: 0,
@@ -2852,7 +2864,10 @@ function genDefaults$1() {
2852
2864
  }
2853
2865
  }
2854
2866
  },
2855
- stylesheetId: 'vuetify-theme-stylesheet'
2867
+ stylesheetId: 'vuetify-theme-stylesheet',
2868
+ scoped: false,
2869
+ unimportant: false,
2870
+ utilities: true
2856
2871
  };
2857
2872
  }
2858
2873
  function parseThemeOptions() {
@@ -2875,21 +2890,21 @@ function parseThemeOptions() {
2875
2890
  function createCssClass(lines, selector, content, scope) {
2876
2891
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2877
2892
  }
2878
- function genCssVariables(theme) {
2893
+ function genCssVariables(theme, prefix) {
2879
2894
  const lightOverlay = theme.dark ? 2 : 1;
2880
2895
  const darkOverlay = theme.dark ? 1 : 2;
2881
2896
  const variables = [];
2882
2897
  for (const [key, value] of Object.entries(theme.colors)) {
2883
2898
  const rgb = parseColor(value);
2884
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2899
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2885
2900
  if (!key.startsWith('on-')) {
2886
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2901
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2887
2902
  }
2888
2903
  }
2889
2904
  for (const [key, value] of Object.entries(theme.variables)) {
2890
2905
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2891
2906
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2892
- variables.push(`--v-${key}: ${rgb ?? value}`);
2907
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2893
2908
  }
2894
2909
  return variables;
2895
2910
  }
@@ -2933,7 +2948,8 @@ function getScopedSelector(selector, scope) {
2933
2948
  const scopeSelector = `:where(${scope})`;
2934
2949
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2935
2950
  }
2936
- function upsertStyles(styleEl, styles) {
2951
+ function upsertStyles(id, cspNonce, styles) {
2952
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2937
2953
  if (!styleEl) return;
2938
2954
  styleEl.innerHTML = styles;
2939
2955
  }
@@ -2953,8 +2969,17 @@ function getOrCreateStyleElement(id, cspNonce) {
2953
2969
  // Composables
2954
2970
  function createTheme(options) {
2955
2971
  const parsedOptions = parseThemeOptions(options);
2956
- const name = shallowRef(parsedOptions.defaultTheme);
2972
+ const _name = shallowRef(parsedOptions.defaultTheme);
2957
2973
  const themes = ref(parsedOptions.themes);
2974
+ const systemName = shallowRef('light');
2975
+ const name = computed({
2976
+ get() {
2977
+ return _name.value === 'system' ? systemName.value : _name.value;
2978
+ },
2979
+ set(val) {
2980
+ _name.value = val;
2981
+ }
2982
+ });
2958
2983
  const computedThemes = computed(() => {
2959
2984
  const acc = {};
2960
2985
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2975,28 +3000,49 @@ function createTheme(options) {
2975
3000
  const current = toRef(() => computedThemes.value[name.value]);
2976
3001
  const styles = computed(() => {
2977
3002
  const lines = [];
3003
+ const important = parsedOptions.unimportant ? '' : ' !important';
3004
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2978
3005
  if (current.value?.dark) {
2979
3006
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2980
3007
  }
2981
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
3008
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2982
3009
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2983
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2984
- }
2985
- const bgLines = [];
2986
- const fgLines = [];
2987
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2988
- for (const key of colors) {
2989
- if (key.startsWith('on-')) {
2990
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2991
- } else {
2992
- createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`], parsedOptions.scope);
2993
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2994
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
3010
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
3011
+ }
3012
+ if (parsedOptions.utilities) {
3013
+ const bgLines = [];
3014
+ const fgLines = [];
3015
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
3016
+ for (const key of colors) {
3017
+ if (key.startsWith('on-')) {
3018
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
3019
+ } else {
3020
+ createCssClass(bgLines, `.${scoped}bg-${key}`, [`--${parsedOptions.prefix}theme-overlay-multiplier: var(--${parsedOptions.prefix}theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`, `color: rgb(var(--${parsedOptions.prefix}theme-on-${key}))${important}`], parsedOptions.scope);
3021
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
3022
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
3023
+ }
2995
3024
  }
3025
+ lines.push(...bgLines, ...fgLines);
2996
3026
  }
2997
- lines.push(...bgLines, ...fgLines);
2998
3027
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2999
3028
  });
3029
+ const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
3030
+ const themeNames = toRef(() => Object.keys(computedThemes.value));
3031
+ if (SUPPORTS_MATCH_MEDIA) {
3032
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
3033
+ function updateSystemName() {
3034
+ systemName.value = media.matches ? 'dark' : 'light';
3035
+ }
3036
+ updateSystemName();
3037
+ media.addEventListener('change', updateSystemName, {
3038
+ passive: true
3039
+ });
3040
+ if (getCurrentScope()) {
3041
+ onScopeDispose(() => {
3042
+ media.removeEventListener('change', updateSystemName);
3043
+ });
3044
+ }
3045
+ }
3000
3046
  function install(app) {
3001
3047
  if (parsedOptions.isDisabled) return;
3002
3048
  const head = app._context.provides.usehead;
@@ -3034,22 +3080,55 @@ function createTheme(options) {
3034
3080
  updateStyles();
3035
3081
  }
3036
3082
  function updateStyles() {
3037
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
3083
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
3038
3084
  }
3039
3085
  }
3040
3086
  }
3041
- const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
3087
+ function change(themeName) {
3088
+ if (!themeNames.value.includes(themeName)) {
3089
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
3090
+ return;
3091
+ }
3092
+ name.value = themeName;
3093
+ }
3094
+ function cycle() {
3095
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
3096
+ const currentIndex = themeArray.indexOf(name.value);
3097
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
3098
+ change(themeArray[nextIndex]);
3099
+ }
3100
+ function toggle() {
3101
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
3102
+ cycle(themeArray);
3103
+ }
3104
+ const globalName = new Proxy(name, {
3105
+ get(target, prop) {
3106
+ return target[prop];
3107
+ },
3108
+ set(target, prop, val) {
3109
+ if (prop === 'value') {
3110
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
3111
+ }
3112
+ // @ts-expect-error
3113
+ target[prop] = val;
3114
+ return true;
3115
+ }
3116
+ });
3042
3117
  return {
3043
3118
  install,
3119
+ change,
3120
+ cycle,
3121
+ toggle,
3044
3122
  isDisabled: parsedOptions.isDisabled,
3045
3123
  name,
3046
3124
  themes,
3047
3125
  current,
3048
3126
  computedThemes,
3127
+ prefix: parsedOptions.prefix,
3049
3128
  themeClasses,
3050
3129
  styles,
3051
3130
  global: {
3052
- name,
3131
+ name: globalName,
3053
3132
  current
3054
3133
  }
3055
3134
  };
@@ -3060,7 +3139,7 @@ function provideTheme(props) {
3060
3139
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3061
3140
  const name = toRef(() => props.theme ?? theme.name.value);
3062
3141
  const current = toRef(() => theme.themes.value[name.value]);
3063
- const themeClasses = toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
3142
+ const themeClasses = toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
3064
3143
  const newTheme = {
3065
3144
  ...theme,
3066
3145
  name,
@@ -4604,9 +4683,15 @@ function useVariant(props) {
4604
4683
  };
4605
4684
  }
4606
4685
 
4686
+ // Types
4687
+
4607
4688
  const makeVBtnGroupProps = propsFactory({
4608
4689
  baseColor: String,
4609
4690
  divided: Boolean,
4691
+ direction: {
4692
+ type: String,
4693
+ default: 'horizontal'
4694
+ },
4610
4695
  ...makeBorderProps(),
4611
4696
  ...makeComponentProps(),
4612
4697
  ...makeDensityProps(),
@@ -4640,7 +4725,7 @@ const VBtnGroup = genericComponent()({
4640
4725
  } = useRounded(props);
4641
4726
  provideDefaults({
4642
4727
  VBtn: {
4643
- height: 'auto',
4728
+ height: toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4644
4729
  baseColor: toRef(() => props.baseColor),
4645
4730
  color: toRef(() => props.color),
4646
4731
  density: toRef(() => props.density),
@@ -4650,7 +4735,7 @@ const VBtnGroup = genericComponent()({
4650
4735
  });
4651
4736
  useRender(() => {
4652
4737
  return createVNode(props.tag, {
4653
- "class": ['v-btn-group', {
4738
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4654
4739
  'v-btn-group--divided': props.divided
4655
4740
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4656
4741
  "style": props.style
@@ -10382,8 +10467,27 @@ function connectedLocationStrategy(data, props, contentStyles) {
10382
10467
  return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
10383
10468
  });
10384
10469
  let observe = false;
10470
+ let lastFrame = -1;
10471
+ const flipped = new CircularBuffer(4);
10385
10472
  const observer = new ResizeObserver(() => {
10386
- if (observe) updateLocation();
10473
+ if (!observe) return;
10474
+
10475
+ // Detect consecutive frames
10476
+ requestAnimationFrame(newTime => {
10477
+ if (newTime !== lastFrame) flipped.clear();
10478
+ requestAnimationFrame(newNewTime => {
10479
+ lastFrame = newNewTime;
10480
+ });
10481
+ });
10482
+ if (flipped.isFull) {
10483
+ const values = flipped.values();
10484
+ if (deepEqual(values.at(-1), values.at(-3))) {
10485
+ // Flipping is causing a container resize loop
10486
+ return;
10487
+ }
10488
+ }
10489
+ const result = updateLocation();
10490
+ if (result) flipped.push(result.flipped);
10387
10491
  });
10388
10492
  watch([data.target, data.contentEl], (_ref, _ref2) => {
10389
10493
  let [newTarget, newContentEl] = _ref;
@@ -10598,7 +10702,8 @@ function connectedLocationStrategy(data, props, contentStyles) {
10598
10702
  });
10599
10703
  return {
10600
10704
  available,
10601
- contentBox
10705
+ contentBox,
10706
+ flipped
10602
10707
  };
10603
10708
  }
10604
10709
  watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
@@ -12595,7 +12700,12 @@ function useVirtual(props, items) {
12595
12700
  }
12596
12701
  function calculateOffset(index) {
12597
12702
  index = clamp(index, 0, items.value.length - 1);
12598
- return offsets[index] || 0;
12703
+ const whole = Math.floor(index);
12704
+ const fraction = index % 1;
12705
+ const next = whole + 1;
12706
+ const wholeOffset = offsets[whole] || 0;
12707
+ const nextOffset = offsets[next] || wholeOffset;
12708
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12599
12709
  }
12600
12710
  function calculateIndex(scrollTop) {
12601
12711
  return binaryClosest(offsets, scrollTop);
@@ -29181,7 +29291,7 @@ function createVuetify$1() {
29181
29291
  };
29182
29292
  });
29183
29293
  }
29184
- const version$1 = "3.8.2-master.2025-04-27";
29294
+ const version$1 = "3.8.3-dev.2025-04-29";
29185
29295
  createVuetify$1.version = version$1;
29186
29296
 
29187
29297
  // Vue's inject() can only be used in setup
@@ -29206,7 +29316,7 @@ const createVuetify = function () {
29206
29316
  ...options
29207
29317
  });
29208
29318
  };
29209
- const version = "3.8.2-master.2025-04-27";
29319
+ const version = "3.8.3-dev.2025-04-29";
29210
29320
  createVuetify.version = version;
29211
29321
 
29212
29322
  export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useLayout, useLocale, useRtl, useTheme, version };