@vuetify/nightly 3.8.3-master.2025-05-05 → 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 (84) hide show
  1. package/CHANGELOG.md +14 -29
  2. package/dist/json/attributes.json +3140 -3132
  3. package/dist/json/importMap-labs.json +14 -14
  4. package/dist/json/importMap.json +148 -148
  5. package/dist/json/tags.json +2 -0
  6. package/dist/json/web-types.json +5887 -5867
  7. package/dist/vuetify-labs.cjs +162 -72
  8. package/dist/vuetify-labs.css +3608 -3581
  9. package/dist/vuetify-labs.d.ts +135 -102
  10. package/dist/vuetify-labs.esm.js +163 -73
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +162 -72
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +141 -39
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +4998 -4971
  17. package/dist/vuetify.d.ts +164 -131
  18. package/dist/vuetify.esm.js +142 -40
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +141 -39
  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 +55 -55
  40. package/lib/components/VDataTable/VDataTableVirtual.d.ts +55 -55
  41. package/lib/components/VDataTable/composables/headers.d.ts +75 -75
  42. package/lib/components/VDatePicker/VDatePicker.d.ts +3 -3
  43. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +6 -6
  44. package/lib/components/VFileInput/VFileInput.css +4 -0
  45. package/lib/components/VFileInput/VFileInput.js +21 -3
  46. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  47. package/lib/components/VFileInput/VFileInput.sass +4 -0
  48. package/lib/components/VInput/VInput.d.ts +1 -1
  49. package/lib/components/VNumberInput/VNumberInput.d.ts +3 -3
  50. package/lib/components/VOverlay/VOverlay.css +1 -1
  51. package/lib/components/VOverlay/_variables.scss +1 -1
  52. package/lib/components/VOverlay/locationStrategies.js +1 -1
  53. package/lib/components/VOverlay/locationStrategies.js.map +1 -1
  54. package/lib/components/VSelect/VSelect.d.ts +3 -3
  55. package/lib/components/VTabs/VTabs.d.ts +6 -6
  56. package/lib/components/transitions/dialog-transition.js +3 -3
  57. package/lib/components/transitions/dialog-transition.js.map +1 -1
  58. package/lib/composables/calendar.d.ts +1 -0
  59. package/lib/composables/calendar.js.map +1 -1
  60. package/lib/composables/theme.d.ts +6 -1
  61. package/lib/composables/theme.js +94 -26
  62. package/lib/composables/theme.js.map +1 -1
  63. package/lib/composables/virtual.js +6 -1
  64. package/lib/composables/virtual.js.map +1 -1
  65. package/lib/entry-bundler.d.ts +6 -6
  66. package/lib/entry-bundler.js +1 -1
  67. package/lib/entry-bundler.js.map +1 -1
  68. package/lib/framework.d.ts +56 -51
  69. package/lib/framework.js +1 -1
  70. package/lib/framework.js.map +1 -1
  71. package/lib/labs/VCalendar/VCalendar.d.ts +3 -3
  72. package/lib/labs/VCalendar/VCalendarDay.d.ts +3 -3
  73. package/lib/labs/VCalendar/VCalendarInterval.d.ts +3 -3
  74. package/lib/labs/VCalendar/VCalendarMonthDay.d.ts +3 -3
  75. package/lib/labs/VDateInput/VDateInput.d.ts +9 -9
  76. package/lib/labs/VFileUpload/VFileUpload.js +19 -31
  77. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  78. package/lib/labs/VTimePicker/VTimePickerClock.js +2 -2
  79. package/lib/labs/VTimePicker/VTimePickerClock.js.map +1 -1
  80. package/lib/util/globals.d.ts +1 -0
  81. package/lib/util/globals.js +1 -0
  82. package/lib/util/globals.js.map +1 -1
  83. package/lib/util/helpers.js.map +1 -1
  84. package/package.json +6 -6
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.3-master.2025-05-05
2
+ * Vuetify v3.8.4-dev.2025-05-07
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -85,6 +85,7 @@
85
85
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
86
86
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
87
87
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
88
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
88
89
 
89
90
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
90
91
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -2299,6 +2300,7 @@
2299
2300
  function genDefaults$2() {
2300
2301
  return {
2301
2302
  defaultTheme: 'light',
2303
+ prefix: 'v-',
2302
2304
  variations: {
2303
2305
  colors: [],
2304
2306
  lighten: 0,
@@ -2380,7 +2382,10 @@
2380
2382
  }
2381
2383
  }
2382
2384
  },
2383
- stylesheetId: 'vuetify-theme-stylesheet'
2385
+ stylesheetId: 'vuetify-theme-stylesheet',
2386
+ scoped: false,
2387
+ unimportant: false,
2388
+ utilities: true
2384
2389
  };
2385
2390
  }
2386
2391
  function parseThemeOptions() {
@@ -2403,21 +2408,21 @@
2403
2408
  function createCssClass(lines, selector, content, scope) {
2404
2409
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2405
2410
  }
2406
- function genCssVariables(theme) {
2411
+ function genCssVariables(theme, prefix) {
2407
2412
  const lightOverlay = theme.dark ? 2 : 1;
2408
2413
  const darkOverlay = theme.dark ? 1 : 2;
2409
2414
  const variables = [];
2410
2415
  for (const [key, value] of Object.entries(theme.colors)) {
2411
2416
  const rgb = parseColor(value);
2412
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2417
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2413
2418
  if (!key.startsWith('on-')) {
2414
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2419
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2415
2420
  }
2416
2421
  }
2417
2422
  for (const [key, value] of Object.entries(theme.variables)) {
2418
2423
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2419
2424
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2420
- variables.push(`--v-${key}: ${rgb ?? value}`);
2425
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2421
2426
  }
2422
2427
  return variables;
2423
2428
  }
@@ -2461,7 +2466,8 @@
2461
2466
  const scopeSelector = `:where(${scope})`;
2462
2467
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2463
2468
  }
2464
- function upsertStyles(styleEl, styles) {
2469
+ function upsertStyles(id, cspNonce, styles) {
2470
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2465
2471
  if (!styleEl) return;
2466
2472
  styleEl.innerHTML = styles;
2467
2473
  }
@@ -2481,8 +2487,17 @@
2481
2487
  // Composables
2482
2488
  function createTheme(options) {
2483
2489
  const parsedOptions = parseThemeOptions(options);
2484
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2490
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2485
2491
  const themes = vue.ref(parsedOptions.themes);
2492
+ const systemName = vue.shallowRef('light');
2493
+ const name = vue.computed({
2494
+ get() {
2495
+ return _name.value === 'system' ? systemName.value : _name.value;
2496
+ },
2497
+ set(val) {
2498
+ _name.value = val;
2499
+ }
2500
+ });
2486
2501
  const computedThemes = vue.computed(() => {
2487
2502
  const acc = {};
2488
2503
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2503,28 +2518,49 @@
2503
2518
  const current = vue.toRef(() => computedThemes.value[name.value]);
2504
2519
  const styles = vue.computed(() => {
2505
2520
  const lines = [];
2521
+ const important = parsedOptions.unimportant ? '' : ' !important';
2522
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2506
2523
  if (current.value?.dark) {
2507
2524
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2508
2525
  }
2509
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2526
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2510
2527
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2511
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2512
- }
2513
- const bgLines = [];
2514
- const fgLines = [];
2515
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2516
- for (const key of colors) {
2517
- if (key.startsWith('on-')) {
2518
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2519
- } else {
2520
- 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);
2521
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2522
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2528
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2529
+ }
2530
+ if (parsedOptions.utilities) {
2531
+ const bgLines = [];
2532
+ const fgLines = [];
2533
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2534
+ for (const key of colors) {
2535
+ if (key.startsWith('on-')) {
2536
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2537
+ } else {
2538
+ 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);
2539
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2540
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2541
+ }
2523
2542
  }
2543
+ lines.push(...bgLines, ...fgLines);
2524
2544
  }
2525
- lines.push(...bgLines, ...fgLines);
2526
2545
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2527
2546
  });
2547
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2548
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2549
+ if (SUPPORTS_MATCH_MEDIA) {
2550
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2551
+ function updateSystemName() {
2552
+ systemName.value = media.matches ? 'dark' : 'light';
2553
+ }
2554
+ updateSystemName();
2555
+ media.addEventListener('change', updateSystemName, {
2556
+ passive: true
2557
+ });
2558
+ if (vue.getCurrentScope()) {
2559
+ vue.onScopeDispose(() => {
2560
+ media.removeEventListener('change', updateSystemName);
2561
+ });
2562
+ }
2563
+ }
2528
2564
  function install(app) {
2529
2565
  if (parsedOptions.isDisabled) return;
2530
2566
  const head = app._context.provides.usehead;
@@ -2562,22 +2598,55 @@
2562
2598
  updateStyles();
2563
2599
  }
2564
2600
  function updateStyles() {
2565
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2601
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2566
2602
  }
2567
2603
  }
2568
2604
  }
2569
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2605
+ function change(themeName) {
2606
+ if (!themeNames.value.includes(themeName)) {
2607
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2608
+ return;
2609
+ }
2610
+ name.value = themeName;
2611
+ }
2612
+ function cycle() {
2613
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2614
+ const currentIndex = themeArray.indexOf(name.value);
2615
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2616
+ change(themeArray[nextIndex]);
2617
+ }
2618
+ function toggle() {
2619
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2620
+ cycle(themeArray);
2621
+ }
2622
+ const globalName = new Proxy(name, {
2623
+ get(target, prop) {
2624
+ return target[prop];
2625
+ },
2626
+ set(target, prop, val) {
2627
+ if (prop === 'value') {
2628
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2629
+ }
2630
+ // @ts-expect-error
2631
+ target[prop] = val;
2632
+ return true;
2633
+ }
2634
+ });
2570
2635
  return {
2571
2636
  install,
2637
+ change,
2638
+ cycle,
2639
+ toggle,
2572
2640
  isDisabled: parsedOptions.isDisabled,
2573
2641
  name,
2574
2642
  themes,
2575
2643
  current,
2576
2644
  computedThemes,
2645
+ prefix: parsedOptions.prefix,
2577
2646
  themeClasses,
2578
2647
  styles,
2579
2648
  global: {
2580
- name,
2649
+ name: globalName,
2581
2650
  current
2582
2651
  }
2583
2652
  };
@@ -2588,7 +2657,7 @@
2588
2657
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2589
2658
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2590
2659
  const current = vue.toRef(() => theme.themes.value[name.value]);
2591
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2660
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2592
2661
  const newTheme = {
2593
2662
  ...theme,
2594
2663
  name,
@@ -2927,10 +2996,10 @@
2927
2996
  async onLeave(el, done) {
2928
2997
  await new Promise(resolve => requestAnimationFrame(resolve));
2929
2998
  let dimensions;
2930
- if (!Array.isArray(props.target) && !props.target.offsetParent && saved.has(el)) {
2931
- dimensions = saved.get(el);
2932
- } else {
2999
+ if (!saved.has(el) || Array.isArray(props.target) || props.target.offsetParent || props.target.getClientRects().length) {
2933
3000
  dimensions = getDimensions(props.target, el);
3001
+ } else {
3002
+ dimensions = saved.get(el);
2934
3003
  }
2935
3004
  const {
2936
3005
  x,
@@ -4135,9 +4204,15 @@
4135
4204
  };
4136
4205
  }
4137
4206
 
4207
+ // Types
4208
+
4138
4209
  const makeVBtnGroupProps = propsFactory({
4139
4210
  baseColor: String,
4140
4211
  divided: Boolean,
4212
+ direction: {
4213
+ type: String,
4214
+ default: 'horizontal'
4215
+ },
4141
4216
  ...makeBorderProps(),
4142
4217
  ...makeComponentProps(),
4143
4218
  ...makeDensityProps(),
@@ -4171,7 +4246,7 @@
4171
4246
  } = useRounded(props);
4172
4247
  provideDefaults({
4173
4248
  VBtn: {
4174
- height: 'auto',
4249
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4175
4250
  baseColor: vue.toRef(() => props.baseColor),
4176
4251
  color: vue.toRef(() => props.color),
4177
4252
  density: vue.toRef(() => props.density),
@@ -4181,7 +4256,7 @@
4181
4256
  });
4182
4257
  useRender(() => {
4183
4258
  return vue.createVNode(props.tag, {
4184
- "class": ['v-btn-group', {
4259
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4185
4260
  'v-btn-group--divided': props.divided
4186
4261
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4187
4262
  "style": props.style
@@ -10168,7 +10243,7 @@
10168
10243
  observe = false;
10169
10244
  requestAnimationFrame(() => observe = true);
10170
10245
  if (!data.target.value || !data.contentEl.value) return;
10171
- if (Array.isArray(data.target.value) || data.target.value.offsetParent) {
10246
+ if (Array.isArray(data.target.value) || data.target.value.offsetParent || data.target.value.getClientRects().length) {
10172
10247
  targetBox = getTargetBox(data.target.value);
10173
10248
  } // Otherwise target element is hidden, use last known value
10174
10249
 
@@ -12356,7 +12431,12 @@
12356
12431
  }
12357
12432
  function calculateOffset(index) {
12358
12433
  index = clamp(index, 0, items.value.length - 1);
12359
- return offsets[index] || 0;
12434
+ const whole = Math.floor(index);
12435
+ const fraction = index % 1;
12436
+ const next = whole + 1;
12437
+ const wholeOffset = offsets[whole] || 0;
12438
+ const nextOffset = offsets[next] || wholeOffset;
12439
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12360
12440
  }
12361
12441
  function calculateIndex(scrollTop) {
12362
12442
  return binaryClosest(offsets, scrollTop);
@@ -13506,6 +13586,11 @@
13506
13586
  menu.value = true;
13507
13587
  }
13508
13588
  });
13589
+ vue.watch(model, value => {
13590
+ if (!props.multiple && !hasSelectionSlot.value) {
13591
+ search.value = value[0]?.title ?? '';
13592
+ }
13593
+ });
13509
13594
  useRender(() => {
13510
13595
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
13511
13596
  const isDirty = model.value.length > 0;
@@ -20333,7 +20418,6 @@
20333
20418
  });
20334
20419
  };
20335
20420
  const VDataTableMobileHeaderCell = () => {
20336
- const headerProps = vue.mergeProps(props.headerProps ?? {} ?? {});
20337
20421
  const displayItems = vue.computed(() => {
20338
20422
  return columns.value.filter(column => column?.sortable && !props.disableSort);
20339
20423
  });
@@ -20346,7 +20430,7 @@
20346
20430
  "tag": "th",
20347
20431
  "class": [...headerCellClasses.value],
20348
20432
  "colspan": headers.value.length + 1
20349
- }, headerProps), {
20433
+ }, props.headerProps), {
20350
20434
  default: () => [vue.createVNode("div", {
20351
20435
  "class": "v-data-table-header__content"
20352
20436
  }, [vue.createVNode(VSelect, {
@@ -23269,6 +23353,7 @@
23269
23353
  const inputRef = vue.ref();
23270
23354
  const isActive = vue.toRef(() => isFocused.value || props.active);
23271
23355
  const isPlainOrUnderlined = vue.computed(() => ['plain', 'underlined'].includes(props.variant));
23356
+ const isDragging = vue.shallowRef(false);
23272
23357
  function onFocus() {
23273
23358
  if (inputRef.value !== document.activeElement) {
23274
23359
  inputRef.value?.focus();
@@ -23295,11 +23380,26 @@
23295
23380
  }
23296
23381
  function onDragover(e) {
23297
23382
  e.preventDefault();
23383
+ e.stopImmediatePropagation();
23384
+ isDragging.value = true;
23385
+ }
23386
+ function onDragleave(e) {
23387
+ e.preventDefault();
23388
+ isDragging.value = false;
23298
23389
  }
23299
23390
  function onDrop(e) {
23300
23391
  e.preventDefault();
23301
- if (!e.dataTransfer) return;
23302
- model.value = [...(e.dataTransfer.files ?? [])];
23392
+ e.stopImmediatePropagation();
23393
+ isDragging.value = false;
23394
+ if (!e.dataTransfer?.files?.length || !inputRef.value) return;
23395
+ const dataTransfer = new DataTransfer();
23396
+ for (const file of e.dataTransfer.files) {
23397
+ dataTransfer.items.add(file);
23398
+ }
23399
+ inputRef.value.files = dataTransfer.files;
23400
+ inputRef.value.dispatchEvent(new Event('change', {
23401
+ bubbles: true
23402
+ }));
23303
23403
  }
23304
23404
  vue.watch(model, newValue => {
23305
23405
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -23321,6 +23421,7 @@
23321
23421
  "modelValue": props.multiple ? model.value : model.value[0],
23322
23422
  "class": ['v-file-input', {
23323
23423
  'v-file-input--chips': !!props.chips,
23424
+ 'v-file-input--dragging': isDragging.value,
23324
23425
  'v-file-input--hide': props.hideInput,
23325
23426
  'v-input--plain-underlined': isPlainOrUnderlined.value
23326
23427
  }, props.class],
@@ -23382,6 +23483,7 @@
23382
23483
  const target = e.target;
23383
23484
  model.value = [...(target.files ?? [])];
23384
23485
  },
23486
+ "onDragleave": onDragleave,
23385
23487
  "onFocus": onFocus,
23386
23488
  "onBlur": blur
23387
23489
  }, slotProps, inputAttrs), null), vue.createVNode("div", {
@@ -29434,43 +29536,31 @@
29434
29536
  densityClasses
29435
29537
  } = useDensity(props);
29436
29538
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
29437
- const dragOver = vue.shallowRef(false);
29539
+ const isDragging = vue.shallowRef(false);
29438
29540
  const vSheetRef = vue.ref(null);
29439
29541
  const inputRef = vue.ref(null);
29440
- vue.onMounted(() => {
29441
- vSheetRef.value?.$el.addEventListener('dragover', onDragOver);
29442
- vSheetRef.value?.$el.addEventListener('drop', onDrop);
29443
- });
29444
- vue.onUnmounted(() => {
29445
- vSheetRef.value?.$el.removeEventListener('dragover', onDragOver);
29446
- vSheetRef.value?.$el.removeEventListener('drop', onDrop);
29447
- });
29448
- function onDragOver(e) {
29542
+ function onDragover(e) {
29449
29543
  e.preventDefault();
29450
29544
  e.stopImmediatePropagation();
29451
- dragOver.value = true;
29545
+ isDragging.value = true;
29452
29546
  }
29453
- function onDragLeave(e) {
29547
+ function onDragleave(e) {
29454
29548
  e.preventDefault();
29455
- dragOver.value = false;
29549
+ isDragging.value = false;
29456
29550
  }
29457
29551
  function onDrop(e) {
29458
29552
  e.preventDefault();
29459
29553
  e.stopImmediatePropagation();
29460
- dragOver.value = false;
29461
- const files = Array.from(e.dataTransfer?.files ?? []);
29462
- if (!files.length) return;
29463
- if (!props.multiple) {
29464
- model.value = [files[0]];
29465
- return;
29466
- }
29467
- const array = model.value.slice();
29468
- for (const file of files) {
29469
- if (!array.some(f => f.name === file.name)) {
29470
- array.push(file);
29471
- }
29472
- }
29473
- model.value = array;
29554
+ isDragging.value = false;
29555
+ if (!e.dataTransfer?.files?.length || !inputRef.value) return;
29556
+ const dataTransfer = new DataTransfer();
29557
+ for (const file of e.dataTransfer.files) {
29558
+ dataTransfer.items.add(file);
29559
+ }
29560
+ inputRef.value.files = dataTransfer.files;
29561
+ inputRef.value.dispatchEvent(new Event('change', {
29562
+ bubbles: true
29563
+ }));
29474
29564
  }
29475
29565
  function onClick() {
29476
29566
  inputRef.value?.click();
@@ -29506,11 +29596,11 @@
29506
29596
  "class": ['v-file-upload', {
29507
29597
  'v-file-upload--clickable': !hasBrowse,
29508
29598
  'v-file-upload--disabled': props.disabled,
29509
- 'v-file-upload--dragging': dragOver.value
29599
+ 'v-file-upload--dragging': isDragging.value
29510
29600
  }, densityClasses.value, props.class],
29511
29601
  "style": [props.style],
29512
- "onDragleave": onDragLeave,
29513
- "onDragover": onDragOver,
29602
+ "onDragleave": onDragleave,
29603
+ "onDragover": onDragover,
29514
29604
  "onDrop": onDrop,
29515
29605
  "onClick": !hasBrowse ? onClick : undefined
29516
29606
  }, rootAttrs), {
@@ -29561,7 +29651,7 @@
29561
29651
  })]), props.subtitle && vue.createVNode("div", {
29562
29652
  "class": "v-file-upload-subtitle"
29563
29653
  }, [props.subtitle])]), vue.createVNode(VOverlay, {
29564
- "model-value": dragOver.value,
29654
+ "model-value": isDragging.value,
29565
29655
  "contained": true,
29566
29656
  "scrim": props.scrim
29567
29657
  }, null), slots.input?.({
@@ -30259,8 +30349,8 @@
30259
30349
  y
30260
30350
  } = getPosition(i);
30261
30351
  return {
30262
- left: `${50 + x * 50}%`,
30263
- top: `${50 + y * 50}%`
30352
+ left: `${Math.round(50 + x * 50)}%`,
30353
+ top: `${Math.round(50 + y * 50)}%`
30264
30354
  };
30265
30355
  }
30266
30356
  function euclidean(p0, p1) {
@@ -31664,7 +31754,7 @@
31664
31754
  };
31665
31755
  });
31666
31756
  }
31667
- const version$1 = "3.8.3-master.2025-05-05";
31757
+ const version$1 = "3.8.4-dev.2025-05-07";
31668
31758
  createVuetify$1.version = version$1;
31669
31759
 
31670
31760
  // Vue's inject() can only be used in setup
@@ -31962,7 +32052,7 @@
31962
32052
 
31963
32053
  /* eslint-disable local-rules/sort-imports */
31964
32054
 
31965
- const version = "3.8.3-master.2025-05-05";
32055
+ const version = "3.8.4-dev.2025-05-07";
31966
32056
 
31967
32057
  /* eslint-disable local-rules/sort-imports */
31968
32058