@vuetify/nightly 3.8.3-master.2025-05-04 → 3.8.4-dev.2025-05-07

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 (88) hide show
  1. package/CHANGELOG.md +14 -24
  2. package/dist/json/attributes.json +2834 -2826
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +156 -156
  5. package/dist/json/tags.json +2 -0
  6. package/dist/json/web-types.json +5151 -5131
  7. package/dist/vuetify-labs.cjs +163 -73
  8. package/dist/vuetify-labs.css +4647 -4620
  9. package/dist/vuetify-labs.d.ts +154 -377
  10. package/dist/vuetify-labs.esm.js +164 -74
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +163 -73
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +142 -40
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +5041 -5014
  17. package/dist/vuetify.d.ts +183 -406
  18. package/dist/vuetify.esm.js +143 -41
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +142 -40
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1182 -1173
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VAutocomplete/VAutocomplete.d.ts +3 -3
  26. package/lib/components/VAutocomplete/VAutocomplete.js +5 -0
  27. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  28. package/lib/components/VBottomNavigation/VBottomNavigation.d.ts +6 -6
  29. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  30. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  31. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  32. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  33. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  34. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  35. package/lib/components/VCombobox/VCombobox.d.ts +3 -3
  36. package/lib/components/VDataTable/VDataTable.d.ts +110 -110
  37. package/lib/components/VDataTable/VDataTableHeaders.js +1 -2
  38. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  39. package/lib/components/VDataTable/VDataTableServer.d.ts +62 -189
  40. package/lib/components/VDataTable/VDataTableServer.js.map +1 -1
  41. package/lib/components/VDataTable/VDataTableVirtual.d.ts +62 -189
  42. package/lib/components/VDataTable/VDataTableVirtual.js.map +1 -1
  43. package/lib/components/VDataTable/composables/headers.d.ts +75 -75
  44. package/lib/components/VDatePicker/VDatePicker.d.ts +3 -3
  45. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +6 -6
  46. package/lib/components/VDialog/VDialog.js +1 -1
  47. package/lib/components/VDialog/VDialog.js.map +1 -1
  48. package/lib/components/VFileInput/VFileInput.css +4 -0
  49. package/lib/components/VFileInput/VFileInput.js +21 -3
  50. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  51. package/lib/components/VFileInput/VFileInput.sass +4 -0
  52. package/lib/components/VInput/VInput.d.ts +1 -1
  53. package/lib/components/VNumberInput/VNumberInput.d.ts +3 -3
  54. package/lib/components/VOverlay/VOverlay.css +1 -1
  55. package/lib/components/VOverlay/_variables.scss +1 -1
  56. package/lib/components/VOverlay/locationStrategies.js +1 -1
  57. package/lib/components/VOverlay/locationStrategies.js.map +1 -1
  58. package/lib/components/VSelect/VSelect.d.ts +3 -3
  59. package/lib/components/VTabs/VTabs.d.ts +6 -6
  60. package/lib/components/transitions/dialog-transition.js +3 -3
  61. package/lib/components/transitions/dialog-transition.js.map +1 -1
  62. package/lib/composables/calendar.d.ts +1 -0
  63. package/lib/composables/calendar.js.map +1 -1
  64. package/lib/composables/theme.d.ts +6 -1
  65. package/lib/composables/theme.js +94 -26
  66. package/lib/composables/theme.js.map +1 -1
  67. package/lib/composables/virtual.js +6 -1
  68. package/lib/composables/virtual.js.map +1 -1
  69. package/lib/entry-bundler.d.ts +6 -6
  70. package/lib/entry-bundler.js +1 -1
  71. package/lib/entry-bundler.js.map +1 -1
  72. package/lib/framework.d.ts +65 -60
  73. package/lib/framework.js +1 -1
  74. package/lib/framework.js.map +1 -1
  75. package/lib/labs/VCalendar/VCalendar.d.ts +3 -3
  76. package/lib/labs/VCalendar/VCalendarDay.d.ts +3 -3
  77. package/lib/labs/VCalendar/VCalendarInterval.d.ts +3 -3
  78. package/lib/labs/VCalendar/VCalendarMonthDay.d.ts +3 -3
  79. package/lib/labs/VDateInput/VDateInput.d.ts +9 -9
  80. package/lib/labs/VFileUpload/VFileUpload.js +19 -31
  81. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  82. package/lib/labs/VTimePicker/VTimePickerClock.js +2 -2
  83. package/lib/labs/VTimePicker/VTimePickerClock.js.map +1 -1
  84. package/lib/util/globals.d.ts +1 -0
  85. package/lib/util/globals.js +1 -0
  86. package/lib/util/globals.js.map +1 -1
  87. package/lib/util/helpers.js.map +1 -1
  88. package/package.json +6 -6
@@ -1,15 +1,16 @@
1
1
  /*!
2
- * Vuetify v3.8.3-master.2025-05-04
2
+ * Vuetify v3.8.4-dev.2025-05-07
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"); }
@@ -2781,6 +2782,7 @@ const makeThemeProps = propsFactory({
2781
2782
  function genDefaults$1() {
2782
2783
  return {
2783
2784
  defaultTheme: 'light',
2785
+ prefix: 'v-',
2784
2786
  variations: {
2785
2787
  colors: [],
2786
2788
  lighten: 0,
@@ -2862,7 +2864,10 @@ function genDefaults$1() {
2862
2864
  }
2863
2865
  }
2864
2866
  },
2865
- stylesheetId: 'vuetify-theme-stylesheet'
2867
+ stylesheetId: 'vuetify-theme-stylesheet',
2868
+ scoped: false,
2869
+ unimportant: false,
2870
+ utilities: true
2866
2871
  };
2867
2872
  }
2868
2873
  function parseThemeOptions() {
@@ -2885,21 +2890,21 @@ function parseThemeOptions() {
2885
2890
  function createCssClass(lines, selector, content, scope) {
2886
2891
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2887
2892
  }
2888
- function genCssVariables(theme) {
2893
+ function genCssVariables(theme, prefix) {
2889
2894
  const lightOverlay = theme.dark ? 2 : 1;
2890
2895
  const darkOverlay = theme.dark ? 1 : 2;
2891
2896
  const variables = [];
2892
2897
  for (const [key, value] of Object.entries(theme.colors)) {
2893
2898
  const rgb = parseColor(value);
2894
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2899
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2895
2900
  if (!key.startsWith('on-')) {
2896
- 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}`);
2897
2902
  }
2898
2903
  }
2899
2904
  for (const [key, value] of Object.entries(theme.variables)) {
2900
2905
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2901
2906
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2902
- variables.push(`--v-${key}: ${rgb ?? value}`);
2907
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2903
2908
  }
2904
2909
  return variables;
2905
2910
  }
@@ -2943,7 +2948,8 @@ function getScopedSelector(selector, scope) {
2943
2948
  const scopeSelector = `:where(${scope})`;
2944
2949
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2945
2950
  }
2946
- function upsertStyles(styleEl, styles) {
2951
+ function upsertStyles(id, cspNonce, styles) {
2952
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2947
2953
  if (!styleEl) return;
2948
2954
  styleEl.innerHTML = styles;
2949
2955
  }
@@ -2963,8 +2969,17 @@ function getOrCreateStyleElement(id, cspNonce) {
2963
2969
  // Composables
2964
2970
  function createTheme(options) {
2965
2971
  const parsedOptions = parseThemeOptions(options);
2966
- const name = shallowRef(parsedOptions.defaultTheme);
2972
+ const _name = shallowRef(parsedOptions.defaultTheme);
2967
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
+ });
2968
2983
  const computedThemes = computed(() => {
2969
2984
  const acc = {};
2970
2985
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2985,28 +3000,49 @@ function createTheme(options) {
2985
3000
  const current = toRef(() => computedThemes.value[name.value]);
2986
3001
  const styles = computed(() => {
2987
3002
  const lines = [];
3003
+ const important = parsedOptions.unimportant ? '' : ' !important';
3004
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2988
3005
  if (current.value?.dark) {
2989
3006
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2990
3007
  }
2991
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
3008
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2992
3009
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2993
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2994
- }
2995
- const bgLines = [];
2996
- const fgLines = [];
2997
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2998
- for (const key of colors) {
2999
- if (key.startsWith('on-')) {
3000
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
3001
- } else {
3002
- 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);
3003
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
3004
- 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
+ }
3005
3024
  }
3025
+ lines.push(...bgLines, ...fgLines);
3006
3026
  }
3007
- lines.push(...bgLines, ...fgLines);
3008
3027
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
3009
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
+ }
3010
3046
  function install(app) {
3011
3047
  if (parsedOptions.isDisabled) return;
3012
3048
  const head = app._context.provides.usehead;
@@ -3044,22 +3080,55 @@ function createTheme(options) {
3044
3080
  updateStyles();
3045
3081
  }
3046
3082
  function updateStyles() {
3047
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
3083
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
3048
3084
  }
3049
3085
  }
3050
3086
  }
3051
- 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
+ });
3052
3117
  return {
3053
3118
  install,
3119
+ change,
3120
+ cycle,
3121
+ toggle,
3054
3122
  isDisabled: parsedOptions.isDisabled,
3055
3123
  name,
3056
3124
  themes,
3057
3125
  current,
3058
3126
  computedThemes,
3127
+ prefix: parsedOptions.prefix,
3059
3128
  themeClasses,
3060
3129
  styles,
3061
3130
  global: {
3062
- name,
3131
+ name: globalName,
3063
3132
  current
3064
3133
  }
3065
3134
  };
@@ -3070,7 +3139,7 @@ function provideTheme(props) {
3070
3139
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3071
3140
  const name = toRef(() => props.theme ?? theme.name.value);
3072
3141
  const current = toRef(() => theme.themes.value[name.value]);
3073
- const themeClasses = toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
3142
+ const themeClasses = toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
3074
3143
  const newTheme = {
3075
3144
  ...theme,
3076
3145
  name,
@@ -3409,10 +3478,10 @@ const VDialogTransition = genericComponent()({
3409
3478
  async onLeave(el, done) {
3410
3479
  await new Promise(resolve => requestAnimationFrame(resolve));
3411
3480
  let dimensions;
3412
- if (!Array.isArray(props.target) && !props.target.offsetParent && saved.has(el)) {
3413
- dimensions = saved.get(el);
3414
- } else {
3481
+ if (!saved.has(el) || Array.isArray(props.target) || props.target.offsetParent || props.target.getClientRects().length) {
3415
3482
  dimensions = getDimensions(props.target, el);
3483
+ } else {
3484
+ dimensions = saved.get(el);
3416
3485
  }
3417
3486
  const {
3418
3487
  x,
@@ -4617,9 +4686,15 @@ function useVariant(props) {
4617
4686
  };
4618
4687
  }
4619
4688
 
4689
+ // Types
4690
+
4620
4691
  const makeVBtnGroupProps = propsFactory({
4621
4692
  baseColor: String,
4622
4693
  divided: Boolean,
4694
+ direction: {
4695
+ type: String,
4696
+ default: 'horizontal'
4697
+ },
4623
4698
  ...makeBorderProps(),
4624
4699
  ...makeComponentProps(),
4625
4700
  ...makeDensityProps(),
@@ -4653,7 +4728,7 @@ const VBtnGroup = genericComponent()({
4653
4728
  } = useRounded(props);
4654
4729
  provideDefaults({
4655
4730
  VBtn: {
4656
- height: 'auto',
4731
+ height: toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4657
4732
  baseColor: toRef(() => props.baseColor),
4658
4733
  color: toRef(() => props.color),
4659
4734
  density: toRef(() => props.density),
@@ -4663,7 +4738,7 @@ const VBtnGroup = genericComponent()({
4663
4738
  });
4664
4739
  useRender(() => {
4665
4740
  return createVNode(props.tag, {
4666
- "class": ['v-btn-group', {
4741
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4667
4742
  'v-btn-group--divided': props.divided
4668
4743
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4669
4744
  "style": props.style
@@ -10442,7 +10517,7 @@ function connectedLocationStrategy(data, props, contentStyles) {
10442
10517
  observe = false;
10443
10518
  requestAnimationFrame(() => observe = true);
10444
10519
  if (!data.target.value || !data.contentEl.value) return;
10445
- if (Array.isArray(data.target.value) || data.target.value.offsetParent) {
10520
+ if (Array.isArray(data.target.value) || data.target.value.offsetParent || data.target.value.getClientRects().length) {
10446
10521
  targetBox = getTargetBox(data.target.value);
10447
10522
  } // Otherwise target element is hidden, use last known value
10448
10523
 
@@ -12630,7 +12705,12 @@ function useVirtual(props, items) {
12630
12705
  }
12631
12706
  function calculateOffset(index) {
12632
12707
  index = clamp(index, 0, items.value.length - 1);
12633
- return offsets[index] || 0;
12708
+ const whole = Math.floor(index);
12709
+ const fraction = index % 1;
12710
+ const next = whole + 1;
12711
+ const wholeOffset = offsets[whole] || 0;
12712
+ const nextOffset = offsets[next] || wholeOffset;
12713
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12634
12714
  }
12635
12715
  function calculateIndex(scrollTop) {
12636
12716
  return binaryClosest(offsets, scrollTop);
@@ -13780,6 +13860,11 @@ const VAutocomplete = genericComponent()({
13780
13860
  menu.value = true;
13781
13861
  }
13782
13862
  });
13863
+ watch(model, value => {
13864
+ if (!props.multiple && !hasSelectionSlot.value) {
13865
+ search.value = value[0]?.title ?? '';
13866
+ }
13867
+ });
13783
13868
  useRender(() => {
13784
13869
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
13785
13870
  const isDirty = model.value.length > 0;
@@ -14399,7 +14484,7 @@ const VDialog = genericComponent()({
14399
14484
  }
14400
14485
  function onAfterEnter() {
14401
14486
  emit('afterEnter');
14402
- if (overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
14487
+ if ((props.scrim || props.retainFocus) && overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
14403
14488
  overlay.value.contentEl.focus({
14404
14489
  preventScroll: true
14405
14490
  });
@@ -20607,7 +20692,6 @@ const VDataTableHeaders = genericComponent()({
20607
20692
  });
20608
20693
  };
20609
20694
  const VDataTableMobileHeaderCell = () => {
20610
- const headerProps = mergeProps(props.headerProps ?? {} ?? {});
20611
20695
  const displayItems = computed(() => {
20612
20696
  return columns.value.filter(column => column?.sortable && !props.disableSort);
20613
20697
  });
@@ -20620,7 +20704,7 @@ const VDataTableHeaders = genericComponent()({
20620
20704
  "tag": "th",
20621
20705
  "class": [...headerCellClasses.value],
20622
20706
  "colspan": headers.value.length + 1
20623
- }, headerProps), {
20707
+ }, props.headerProps), {
20624
20708
  default: () => [createVNode("div", {
20625
20709
  "class": "v-data-table-header__content"
20626
20710
  }, [createVNode(VSelect, {
@@ -23543,6 +23627,7 @@ const VFileInput = genericComponent()({
23543
23627
  const inputRef = ref();
23544
23628
  const isActive = toRef(() => isFocused.value || props.active);
23545
23629
  const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
23630
+ const isDragging = shallowRef(false);
23546
23631
  function onFocus() {
23547
23632
  if (inputRef.value !== document.activeElement) {
23548
23633
  inputRef.value?.focus();
@@ -23569,11 +23654,26 @@ const VFileInput = genericComponent()({
23569
23654
  }
23570
23655
  function onDragover(e) {
23571
23656
  e.preventDefault();
23657
+ e.stopImmediatePropagation();
23658
+ isDragging.value = true;
23659
+ }
23660
+ function onDragleave(e) {
23661
+ e.preventDefault();
23662
+ isDragging.value = false;
23572
23663
  }
23573
23664
  function onDrop(e) {
23574
23665
  e.preventDefault();
23575
- if (!e.dataTransfer) return;
23576
- model.value = [...(e.dataTransfer.files ?? [])];
23666
+ e.stopImmediatePropagation();
23667
+ isDragging.value = false;
23668
+ if (!e.dataTransfer?.files?.length || !inputRef.value) return;
23669
+ const dataTransfer = new DataTransfer();
23670
+ for (const file of e.dataTransfer.files) {
23671
+ dataTransfer.items.add(file);
23672
+ }
23673
+ inputRef.value.files = dataTransfer.files;
23674
+ inputRef.value.dispatchEvent(new Event('change', {
23675
+ bubbles: true
23676
+ }));
23577
23677
  }
23578
23678
  watch(model, newValue => {
23579
23679
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -23595,6 +23695,7 @@ const VFileInput = genericComponent()({
23595
23695
  "modelValue": props.multiple ? model.value : model.value[0],
23596
23696
  "class": ['v-file-input', {
23597
23697
  'v-file-input--chips': !!props.chips,
23698
+ 'v-file-input--dragging': isDragging.value,
23598
23699
  'v-file-input--hide': props.hideInput,
23599
23700
  'v-input--plain-underlined': isPlainOrUnderlined.value
23600
23701
  }, props.class],
@@ -23656,6 +23757,7 @@ const VFileInput = genericComponent()({
23656
23757
  const target = e.target;
23657
23758
  model.value = [...(target.files ?? [])];
23658
23759
  },
23760
+ "onDragleave": onDragleave,
23659
23761
  "onFocus": onFocus,
23660
23762
  "onBlur": blur
23661
23763
  }, slotProps, inputAttrs), null), createVNode("div", {
@@ -29216,7 +29318,7 @@ function createVuetify$1() {
29216
29318
  };
29217
29319
  });
29218
29320
  }
29219
- const version$1 = "3.8.3-master.2025-05-04";
29321
+ const version$1 = "3.8.4-dev.2025-05-07";
29220
29322
  createVuetify$1.version = version$1;
29221
29323
 
29222
29324
  // Vue's inject() can only be used in setup
@@ -29241,7 +29343,7 @@ const createVuetify = function () {
29241
29343
  ...options
29242
29344
  });
29243
29345
  };
29244
- const version = "3.8.3-master.2025-05-04";
29346
+ const version = "3.8.4-dev.2025-05-07";
29245
29347
  createVuetify.version = version;
29246
29348
 
29247
29349
  export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useLayout, useLocale, useRtl, useTheme, version };