@vuetify/nightly 3.9.0-dev.2025-07-08 → 3.9.0-dev.2025-07-16

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 (55) hide show
  1. package/CHANGELOG.md +14 -3
  2. package/dist/json/attributes.json +3826 -3806
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +168 -168
  5. package/dist/json/tags.json +5 -0
  6. package/dist/json/web-types.json +6992 -6922
  7. package/dist/vuetify-labs.cjs +216 -27
  8. package/dist/vuetify-labs.css +4659 -4657
  9. package/dist/vuetify-labs.d.ts +119 -57
  10. package/dist/vuetify-labs.esm.js +216 -27
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +216 -27
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +178 -18
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +4036 -4034
  17. package/dist/vuetify.d.ts +109 -57
  18. package/dist/vuetify.esm.js +178 -18
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +178 -18
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +718 -696
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VAutocomplete/VAutocomplete.js +1 -0
  26. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  27. package/lib/components/VCombobox/VCombobox.js +1 -0
  28. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  29. package/lib/components/VFileInput/VFileInput.d.ts +15 -0
  30. package/lib/components/VFileInput/VFileInput.js +38 -9
  31. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  32. package/lib/components/VList/VList.js +2 -1
  33. package/lib/components/VList/VList.js.map +1 -1
  34. package/lib/components/VList/VListItem.js +7 -1
  35. package/lib/components/VList/VListItem.js.map +1 -1
  36. package/lib/components/VProgressLinear/VProgressLinear.css +1 -1
  37. package/lib/components/VProgressLinear/VProgressLinear.d.ts +75 -0
  38. package/lib/components/VProgressLinear/VProgressLinear.js +32 -6
  39. package/lib/components/VProgressLinear/VProgressLinear.js.map +1 -1
  40. package/lib/components/VProgressLinear/VProgressLinear.sass +2 -2
  41. package/lib/components/VProgressLinear/chunks.d.ts +55 -0
  42. package/lib/components/VProgressLinear/chunks.js +62 -0
  43. package/lib/components/VProgressLinear/chunks.js.map +1 -0
  44. package/lib/components/VSelect/VSelect.js +1 -0
  45. package/lib/components/VSelect/VSelect.js.map +1 -1
  46. package/lib/composables/fileFilter.d.ts +18 -0
  47. package/lib/composables/fileFilter.js +38 -0
  48. package/lib/composables/fileFilter.js.map +1 -0
  49. package/lib/entry-bundler.js +1 -1
  50. package/lib/framework.d.ts +57 -57
  51. package/lib/framework.js +1 -1
  52. package/lib/labs/VFileUpload/VFileUpload.d.ts +15 -0
  53. package/lib/labs/VFileUpload/VFileUpload.js +39 -9
  54. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  55. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.9.0-dev.2025-07-08
2
+ * Vuetify v3.9.0-dev.2025-07-16
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -5186,6 +5186,69 @@ function useLocation(props) {
5186
5186
  };
5187
5187
  }
5188
5188
 
5189
+ // Utilities
5190
+
5191
+ // Types
5192
+
5193
+ // Composables
5194
+ const makeChunksProps = propsFactory({
5195
+ chunkCount: {
5196
+ type: [Number, String],
5197
+ default: null
5198
+ },
5199
+ chunkWidth: {
5200
+ type: [Number, String],
5201
+ default: null
5202
+ },
5203
+ chunkGap: {
5204
+ type: [Number, String],
5205
+ default: 4
5206
+ }
5207
+ }, 'chunks');
5208
+ function useChunks(props, containerWidth) {
5209
+ const hasChunks = toRef(() => !!props.chunkCount || !!props.chunkWidth);
5210
+ const chunkWidth = computed(() => {
5211
+ const containerSize = toValue(containerWidth);
5212
+ if (!containerSize) {
5213
+ return 0;
5214
+ }
5215
+ if (!props.chunkCount) {
5216
+ return Number(props.chunkWidth);
5217
+ }
5218
+ const count = Number(props.chunkCount);
5219
+ const availableWidth = containerSize - Number(props.chunkGap) * (count - 1);
5220
+ return availableWidth / count;
5221
+ });
5222
+ const chunkGap = toRef(() => Number(props.chunkGap));
5223
+ const chunksMaskStyles = computed(() => {
5224
+ if (!hasChunks.value) {
5225
+ return {};
5226
+ }
5227
+ const chunkGapPx = convertToUnit(chunkGap.value);
5228
+ const chunkWidthPx = convertToUnit(chunkWidth.value);
5229
+ return {
5230
+ maskRepeat: 'repeat-x',
5231
+ maskImage: `linear-gradient(90deg, #000, #000 ${chunkWidthPx}, transparent ${chunkWidthPx}, transparent)`,
5232
+ maskSize: `calc(${chunkWidthPx} + ${chunkGapPx}) 100%`
5233
+ };
5234
+ });
5235
+ function snapValueToChunk(val) {
5236
+ const containerSize = toValue(containerWidth);
5237
+ if (!containerSize) {
5238
+ return val;
5239
+ }
5240
+ const gapRelativeSize = 100 * chunkGap.value / containerSize;
5241
+ const chunkRelativeSize = 100 * (chunkWidth.value + chunkGap.value) / containerSize;
5242
+ const filledChunks = Math.floor((val + gapRelativeSize) / chunkRelativeSize);
5243
+ return clamp(0, filledChunks * chunkRelativeSize - gapRelativeSize / 2, 100);
5244
+ }
5245
+ return {
5246
+ hasChunks,
5247
+ chunksMaskStyles,
5248
+ snapValueToChunk
5249
+ };
5250
+ }
5251
+
5189
5252
  const makeVProgressLinearProps = propsFactory({
5190
5253
  absolute: Boolean,
5191
5254
  active: {
@@ -5220,6 +5283,7 @@ const makeVProgressLinearProps = propsFactory({
5220
5283
  stream: Boolean,
5221
5284
  striped: Boolean,
5222
5285
  roundedBar: Boolean,
5286
+ ...makeChunksProps(),
5223
5287
  ...makeComponentProps(),
5224
5288
  ...makeLocationProps({
5225
5289
  location: 'top'
@@ -5238,6 +5302,7 @@ const VProgressLinear = genericComponent()({
5238
5302
  let {
5239
5303
  slots
5240
5304
  } = _ref;
5305
+ const root = ref();
5241
5306
  const progress = useProxiedModel(props, 'modelValue');
5242
5307
  const {
5243
5308
  isRtl,
@@ -5279,6 +5344,24 @@ const VProgressLinear = genericComponent()({
5279
5344
  const isReversed = computed(() => isRtl.value !== props.reverse);
5280
5345
  const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
5281
5346
  const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
5347
+ const containerWidth = shallowRef(0);
5348
+ const {
5349
+ hasChunks,
5350
+ chunksMaskStyles,
5351
+ snapValueToChunk
5352
+ } = useChunks(props, containerWidth);
5353
+ useToggleScope(hasChunks, () => {
5354
+ const {
5355
+ resizeRef
5356
+ } = useResizeObserver(entries => containerWidth.value = entries[0].contentRect.width);
5357
+ watchEffect(() => resizeRef.value = root.value);
5358
+ });
5359
+ const bufferWidth = computed(() => {
5360
+ return hasChunks.value ? snapValueToChunk(normalizedBuffer.value) : normalizedBuffer.value;
5361
+ });
5362
+ const barWidth = computed(() => {
5363
+ return hasChunks.value ? snapValueToChunk(normalizedValue.value) : normalizedValue.value;
5364
+ });
5282
5365
  function handleClick(e) {
5283
5366
  if (!intersectionRef.value) return;
5284
5367
  const {
@@ -5289,8 +5372,11 @@ const VProgressLinear = genericComponent()({
5289
5372
  const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
5290
5373
  progress.value = Math.round(value / width * max.value);
5291
5374
  }
5375
+ watchEffect(() => {
5376
+ intersectionRef.value = root.value;
5377
+ });
5292
5378
  useRender(() => createVNode(props.tag, {
5293
- "ref": intersectionRef,
5379
+ "ref": root,
5294
5380
  "class": normalizeClass(['v-progress-linear', {
5295
5381
  'v-progress-linear--absolute': props.absolute,
5296
5382
  'v-progress-linear--active': props.active && isIntersecting.value,
@@ -5305,7 +5391,7 @@ const VProgressLinear = genericComponent()({
5305
5391
  height: props.active ? convertToUnit(height.value) : 0,
5306
5392
  '--v-progress-linear-height': convertToUnit(height.value),
5307
5393
  ...(props.absolute ? locationStyles.value : {})
5308
- }, props.style]),
5394
+ }, chunksMaskStyles.value, props.style]),
5309
5395
  "role": "progressbar",
5310
5396
  "aria-hidden": props.active ? 'false' : 'true',
5311
5397
  "aria-valuemin": "0",
@@ -5335,7 +5421,7 @@ const VProgressLinear = genericComponent()({
5335
5421
  "class": normalizeClass(['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined]),
5336
5422
  "style": normalizeStyle([bufferColorStyles.value, {
5337
5423
  opacity: parseFloat(props.bufferOpacity),
5338
- width: convertToUnit(normalizedBuffer.value, '%')
5424
+ width: convertToUnit(bufferWidth.value, '%')
5339
5425
  }])
5340
5426
  }, null), createVNode(Transition, {
5341
5427
  "name": transition.value
@@ -5343,7 +5429,7 @@ const VProgressLinear = genericComponent()({
5343
5429
  default: () => [!props.indeterminate ? createElementVNode("div", {
5344
5430
  "class": normalizeClass(['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined]),
5345
5431
  "style": normalizeStyle([barColorStyles.value, {
5346
- width: convertToUnit(normalizedValue.value, '%')
5432
+ width: convertToUnit(barWidth.value, '%')
5347
5433
  }])
5348
5434
  }, null) : createElementVNode("div", {
5349
5435
  "class": "v-progress-linear__indeterminate"
@@ -9558,6 +9644,11 @@ const VListItem = genericComponent()({
9558
9644
  const isLink = toRef(() => props.link !== false && link.isLink.value);
9559
9645
  const isSelectable = computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
9560
9646
  const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
9647
+ const role = computed(() => list ? isSelectable.value ? 'option' : 'listitem' : undefined);
9648
+ const ariaSelected = computed(() => {
9649
+ if (!isSelectable.value) return undefined;
9650
+ return root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value;
9651
+ });
9561
9652
  const roundedProps = toRef(() => props.rounded || props.nav);
9562
9653
  const color = toRef(() => props.color ?? props.activeColor);
9563
9654
  const variantProps = toRef(() => ({
@@ -9661,7 +9752,8 @@ const VListItem = genericComponent()({
9661
9752
  }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
9662
9753
  "style": [colorStyles.value, dimensionStyles.value, props.style],
9663
9754
  "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
9664
- "aria-selected": isSelectable.value ? root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value : undefined,
9755
+ "aria-selected": ariaSelected.value,
9756
+ "role": role.value,
9665
9757
  "onClick": onClick,
9666
9758
  "onKeydown": isClickable.value && !isLink.value && onKeyDown
9667
9759
  }, link.linkProps), {
@@ -10153,6 +10245,7 @@ const VList = genericComponent()({
10153
10245
  const activeColor = toRef(() => props.activeColor);
10154
10246
  const baseColor = toRef(() => props.baseColor);
10155
10247
  const color = toRef(() => props.color);
10248
+ const isSelectable = toRef(() => props.selectable || props.activatable);
10156
10249
  createList({
10157
10250
  filterable: props.filterable
10158
10251
  });
@@ -10222,7 +10315,7 @@ const VList = genericComponent()({
10222
10315
  }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class]),
10223
10316
  "style": normalizeStyle([backgroundColorStyles.value, dimensionStyles.value, props.style]),
10224
10317
  "tabindex": props.disabled ? -1 : 0,
10225
- "role": "listbox",
10318
+ "role": isSelectable.value ? 'listbox' : 'list',
10226
10319
  "aria-activedescendant": undefined,
10227
10320
  "onFocusin": onFocusin,
10228
10321
  "onFocusout": onFocusout,
@@ -13287,6 +13380,7 @@ const VSelect = genericComponent()({
13287
13380
  "onKeydown": onListKeydown,
13288
13381
  "onFocusin": onFocusin,
13289
13382
  "tabindex": "-1",
13383
+ "selectable": true,
13290
13384
  "aria-live": "polite",
13291
13385
  "aria-label": `${props.label}-list`,
13292
13386
  "color": props.itemColor ?? props.color
@@ -13906,6 +14000,7 @@ const VAutocomplete = genericComponent()({
13906
14000
  "onFocusin": onFocusin,
13907
14001
  "onFocusout": onFocusout,
13908
14002
  "tabindex": "-1",
14003
+ "selectable": true,
13909
14004
  "aria-live": "polite",
13910
14005
  "color": props.itemColor ?? props.color
13911
14006
  }, listEvents, props.listProps), {
@@ -18993,6 +19088,7 @@ const VCombobox = genericComponent()({
18993
19088
  "selected": selectedValues.value,
18994
19089
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18995
19090
  "onMousedown": e => e.preventDefault(),
19091
+ "selectable": true,
18996
19092
  "onKeydown": onListKeydown,
18997
19093
  "onFocusin": onFocusin,
18998
19094
  "onFocusout": onFocusout,
@@ -24091,6 +24187,42 @@ function appendIfDirectory(path, item) {
24091
24187
  return item.isDirectory ? `${path}/${item.name}` : path;
24092
24188
  }
24093
24189
 
24190
+ // Utilities
24191
+ // Composables
24192
+ const makeFileFilterProps = propsFactory({
24193
+ filterByType: String
24194
+ }, 'file-accept');
24195
+ function useFileFilter(props) {
24196
+ const fileFilter = computed(() => props.filterByType ? createFilter(props.filterByType) : null);
24197
+ function filterAccepted(files) {
24198
+ if (fileFilter.value) {
24199
+ const accepted = files.filter(fileFilter.value);
24200
+ return {
24201
+ accepted,
24202
+ rejected: files.filter(f => !accepted.includes(f))
24203
+ };
24204
+ }
24205
+ return {
24206
+ accepted: files,
24207
+ rejected: []
24208
+ };
24209
+ }
24210
+ return {
24211
+ filterAccepted
24212
+ };
24213
+ }
24214
+ function createFilter(v) {
24215
+ const types = v.split(',').map(x => x.trim().toLowerCase());
24216
+ const extensionsToMatch = types.filter(x => x.startsWith('.'));
24217
+ const wildcards = types.filter(x => x.endsWith('/*'));
24218
+ const typesToMatch = types.filter(x => !extensionsToMatch.includes(x) && !wildcards.includes(x));
24219
+ return file => {
24220
+ const extension = file.name.split('.').at(-1)?.toLowerCase() ?? '';
24221
+ const typeGroup = file.type.split('/').at(0)?.toLowerCase() ?? '';
24222
+ return typesToMatch.includes(file.type) || extensionsToMatch.includes(`.${extension}`) || wildcards.includes(`${typeGroup}/*`);
24223
+ };
24224
+ }
24225
+
24094
24226
  // Types
24095
24227
 
24096
24228
  const makeVFileInputProps = propsFactory({
@@ -24123,6 +24255,7 @@ const makeVFileInputProps = propsFactory({
24123
24255
  return wrapInArray(val).every(v => v != null && typeof v === 'object');
24124
24256
  }
24125
24257
  },
24258
+ ...makeFileFilterProps(),
24126
24259
  ...makeVFieldProps({
24127
24260
  clearable: true
24128
24261
  })
@@ -24135,7 +24268,8 @@ const VFileInput = genericComponent()({
24135
24268
  'click:control': e => true,
24136
24269
  'mousedown:control': e => true,
24137
24270
  'update:focused': focused => true,
24138
- 'update:modelValue': files => true
24271
+ 'update:modelValue': files => true,
24272
+ rejected: files => true
24139
24273
  },
24140
24274
  setup(props, _ref) {
24141
24275
  let {
@@ -24146,6 +24280,9 @@ const VFileInput = genericComponent()({
24146
24280
  const {
24147
24281
  t
24148
24282
  } = useLocale();
24283
+ const {
24284
+ filterAccepted
24285
+ } = useFileFilter(props);
24149
24286
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
24150
24287
  const {
24151
24288
  isFocused,
@@ -24219,14 +24356,38 @@ const VFileInput = genericComponent()({
24219
24356
  e.stopImmediatePropagation();
24220
24357
  isDragging.value = false;
24221
24358
  if (!inputRef.value || !hasFilesOrFolders(e)) return;
24359
+ const allDroppedFiles = await handleDrop(e);
24360
+ selectAccepted(allDroppedFiles);
24361
+ }
24362
+ function onFileSelection(e) {
24363
+ if (!e.target || e.repack) return; // prevent loop
24364
+
24365
+ if (!props.filterByType) {
24366
+ const target = e.target;
24367
+ model.value = [...(target.files ?? [])];
24368
+ } else {
24369
+ selectAccepted([...e.target.files]);
24370
+ }
24371
+ }
24372
+ function selectAccepted(files) {
24222
24373
  const dataTransfer = new DataTransfer();
24223
- for (const file of await handleDrop(e)) {
24374
+ const {
24375
+ accepted,
24376
+ rejected
24377
+ } = filterAccepted(files);
24378
+ if (rejected.length) {
24379
+ emit('rejected', rejected);
24380
+ }
24381
+ for (const file of accepted) {
24224
24382
  dataTransfer.items.add(file);
24225
24383
  }
24226
24384
  inputRef.value.files = dataTransfer.files;
24227
- inputRef.value.dispatchEvent(new Event('change', {
24385
+ model.value = [...dataTransfer.files];
24386
+ const event = new Event('change', {
24228
24387
  bubbles: true
24229
- }));
24388
+ });
24389
+ event.repack = true;
24390
+ inputRef.value.dispatchEvent(event);
24230
24391
  }
24231
24392
  watch(model, newValue => {
24232
24393
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -24243,6 +24404,8 @@ const VFileInput = genericComponent()({
24243
24404
  ...inputProps
24244
24405
  } = VInput.filterProps(props);
24245
24406
  const fieldProps = VField.filterProps(props);
24407
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
24408
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
24246
24409
  return createVNode(VInput, mergeProps({
24247
24410
  "ref": vInputRef,
24248
24411
  "modelValue": props.multiple ? model.value : model.value[0],
@@ -24296,6 +24459,7 @@ const VFileInput = genericComponent()({
24296
24459
  return createElementVNode(Fragment, null, [createElementVNode("input", mergeProps({
24297
24460
  "ref": inputRef,
24298
24461
  "type": "file",
24462
+ "accept": inputAccept,
24299
24463
  "readonly": isReadonly.value,
24300
24464
  "disabled": isDisabled.value,
24301
24465
  "multiple": props.multiple,
@@ -24305,11 +24469,7 @@ const VFileInput = genericComponent()({
24305
24469
  if (isReadonly.value) e.preventDefault();
24306
24470
  onFocus();
24307
24471
  },
24308
- "onChange": e => {
24309
- if (!e.target) return;
24310
- const target = e.target;
24311
- model.value = [...(target.files ?? [])];
24312
- },
24472
+ "onChange": onFileSelection,
24313
24473
  "onDragleave": onDragleave,
24314
24474
  "onFocus": onFocus,
24315
24475
  "onBlur": blur
@@ -31814,6 +31974,7 @@ const makeVFileUploadProps = propsFactory({
31814
31974
  },
31815
31975
  showSize: Boolean,
31816
31976
  name: String,
31977
+ ...makeFileFilterProps(),
31817
31978
  ...makeDelayProps(),
31818
31979
  ...makeDensityProps(),
31819
31980
  ...pick(makeVDividerProps({
@@ -31826,11 +31987,13 @@ const VFileUpload = genericComponent()({
31826
31987
  inheritAttrs: false,
31827
31988
  props: makeVFileUploadProps(),
31828
31989
  emits: {
31829
- 'update:modelValue': files => true
31990
+ 'update:modelValue': files => true,
31991
+ rejected: files => true
31830
31992
  },
31831
31993
  setup(props, _ref) {
31832
31994
  let {
31833
31995
  attrs,
31996
+ emit,
31834
31997
  slots
31835
31998
  } = _ref;
31836
31999
  const {
@@ -31839,6 +32002,9 @@ const VFileUpload = genericComponent()({
31839
32002
  const {
31840
32003
  densityClasses
31841
32004
  } = useDensity(props);
32005
+ const {
32006
+ filterAccepted
32007
+ } = useFileFilter(props);
31842
32008
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
31843
32009
  const isDragging = shallowRef(false);
31844
32010
  const vSheetRef = ref(null);
@@ -31860,14 +32026,38 @@ const VFileUpload = genericComponent()({
31860
32026
  e.stopImmediatePropagation();
31861
32027
  isDragging.value = false;
31862
32028
  if (!inputRef.value) return;
32029
+ const allDroppedFiles = await handleDrop(e);
32030
+ selectAccepted(allDroppedFiles);
32031
+ }
32032
+ function onFileSelection(e) {
32033
+ if (!e.target || e.repack) return; // prevent loop
32034
+
32035
+ if (!props.filterByType) {
32036
+ const target = e.target;
32037
+ model.value = [...(target.files ?? [])];
32038
+ } else {
32039
+ selectAccepted([...e.target.files]);
32040
+ }
32041
+ }
32042
+ function selectAccepted(files) {
31863
32043
  const dataTransfer = new DataTransfer();
31864
- for (const file of await handleDrop(e)) {
32044
+ const {
32045
+ accepted,
32046
+ rejected
32047
+ } = filterAccepted(files);
32048
+ if (rejected.length) {
32049
+ emit('rejected', rejected);
32050
+ }
32051
+ for (const file of accepted) {
31865
32052
  dataTransfer.items.add(file);
31866
32053
  }
31867
32054
  inputRef.value.files = dataTransfer.files;
31868
- inputRef.value.dispatchEvent(new Event('change', {
32055
+ model.value = [...dataTransfer.files];
32056
+ const event = new Event('change', {
31869
32057
  bubbles: true
31870
- }));
32058
+ });
32059
+ event.repack = true;
32060
+ inputRef.value.dispatchEvent(event);
31871
32061
  }
31872
32062
  function onClick() {
31873
32063
  inputRef.value?.click();
@@ -31885,17 +32075,16 @@ const VFileUpload = genericComponent()({
31885
32075
  const cardProps = VSheet.filterProps(props);
31886
32076
  const dividerProps = VDivider.filterProps(props);
31887
32077
  const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
32078
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
32079
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
31888
32080
  const inputNode = createElementVNode("input", mergeProps({
31889
32081
  "ref": inputRef,
31890
32082
  "type": "file",
32083
+ "accept": inputAccept,
31891
32084
  "disabled": props.disabled,
31892
32085
  "multiple": props.multiple,
31893
32086
  "name": props.name,
31894
- "onChange": e => {
31895
- if (!e.target) return;
31896
- const target = e.target;
31897
- model.value = [...(target.files ?? [])];
31898
- }
32087
+ "onChange": onFileSelection
31899
32088
  }, inputAttrs), null);
31900
32089
  return createElementVNode(Fragment, null, [createVNode(VSheet, mergeProps({
31901
32090
  "ref": vSheetRef
@@ -33672,7 +33861,7 @@ function createVuetify$1() {
33672
33861
  };
33673
33862
  });
33674
33863
  }
33675
- const version$1 = "3.9.0-dev.2025-07-08";
33864
+ const version$1 = "3.9.0-dev.2025-07-16";
33676
33865
  createVuetify$1.version = version$1;
33677
33866
 
33678
33867
  // Vue's inject() can only be used in setup
@@ -33970,7 +34159,7 @@ var index = /*#__PURE__*/Object.freeze({
33970
34159
 
33971
34160
  /* eslint-disable local-rules/sort-imports */
33972
34161
 
33973
- const version = "3.9.0-dev.2025-07-08";
34162
+ const version = "3.9.0-dev.2025-07-16";
33974
34163
 
33975
34164
  /* eslint-disable local-rules/sort-imports */
33976
34165