@vuetify/nightly 3.9.1-master.2025-07-17 → 3.9.2-dev.2025-07-18

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 (61) hide show
  1. package/CHANGELOG.md +11 -5
  2. package/dist/json/attributes.json +3550 -3530
  3. package/dist/json/importMap-labs.json +12 -12
  4. package/dist/json/importMap.json +180 -180
  5. package/dist/json/tags.json +5 -0
  6. package/dist/json/web-types.json +20050 -6602
  7. package/dist/vuetify-labs.cjs +277 -89
  8. package/dist/vuetify-labs.css +4411 -4409
  9. package/dist/vuetify-labs.d.ts +124 -62
  10. package/dist/vuetify-labs.esm.js +277 -89
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +277 -89
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +239 -80
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +2666 -2664
  17. package/dist/vuetify.d.ts +114 -62
  18. package/dist/vuetify.esm.js +239 -80
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +239 -80
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +724 -702
  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/components/VTreeview/VTreeview.js +2 -3
  47. package/lib/components/VTreeview/VTreeview.js.map +1 -1
  48. package/lib/components/VTreeview/VTreeviewChildren.js +59 -59
  49. package/lib/components/VTreeview/VTreeviewChildren.js.map +1 -1
  50. package/lib/composables/fileFilter.d.ts +18 -0
  51. package/lib/composables/fileFilter.js +38 -0
  52. package/lib/composables/fileFilter.js.map +1 -0
  53. package/lib/entry-bundler.js +1 -1
  54. package/lib/entry-bundler.js.map +1 -1
  55. package/lib/framework.d.ts +62 -62
  56. package/lib/framework.js +1 -1
  57. package/lib/framework.js.map +1 -1
  58. package/lib/labs/VFileUpload/VFileUpload.d.ts +15 -0
  59. package/lib/labs/VFileUpload/VFileUpload.js +39 -9
  60. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  61. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.9.1-master.2025-07-17
2
+ * Vuetify v3.9.2-dev.2025-07-18
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -5165,6 +5165,69 @@ function useLocation(props) {
5165
5165
  };
5166
5166
  }
5167
5167
 
5168
+ // Utilities
5169
+
5170
+ // Types
5171
+
5172
+ // Composables
5173
+ const makeChunksProps = propsFactory({
5174
+ chunkCount: {
5175
+ type: [Number, String],
5176
+ default: null
5177
+ },
5178
+ chunkWidth: {
5179
+ type: [Number, String],
5180
+ default: null
5181
+ },
5182
+ chunkGap: {
5183
+ type: [Number, String],
5184
+ default: 4
5185
+ }
5186
+ }, 'chunks');
5187
+ function useChunks(props, containerWidth) {
5188
+ const hasChunks = toRef(() => !!props.chunkCount || !!props.chunkWidth);
5189
+ const chunkWidth = computed(() => {
5190
+ const containerSize = toValue(containerWidth);
5191
+ if (!containerSize) {
5192
+ return 0;
5193
+ }
5194
+ if (!props.chunkCount) {
5195
+ return Number(props.chunkWidth);
5196
+ }
5197
+ const count = Number(props.chunkCount);
5198
+ const availableWidth = containerSize - Number(props.chunkGap) * (count - 1);
5199
+ return availableWidth / count;
5200
+ });
5201
+ const chunkGap = toRef(() => Number(props.chunkGap));
5202
+ const chunksMaskStyles = computed(() => {
5203
+ if (!hasChunks.value) {
5204
+ return {};
5205
+ }
5206
+ const chunkGapPx = convertToUnit(chunkGap.value);
5207
+ const chunkWidthPx = convertToUnit(chunkWidth.value);
5208
+ return {
5209
+ maskRepeat: 'repeat-x',
5210
+ maskImage: `linear-gradient(90deg, #000, #000 ${chunkWidthPx}, transparent ${chunkWidthPx}, transparent)`,
5211
+ maskSize: `calc(${chunkWidthPx} + ${chunkGapPx}) 100%`
5212
+ };
5213
+ });
5214
+ function snapValueToChunk(val) {
5215
+ const containerSize = toValue(containerWidth);
5216
+ if (!containerSize) {
5217
+ return val;
5218
+ }
5219
+ const gapRelativeSize = 100 * chunkGap.value / containerSize;
5220
+ const chunkRelativeSize = 100 * (chunkWidth.value + chunkGap.value) / containerSize;
5221
+ const filledChunks = Math.floor((val + gapRelativeSize) / chunkRelativeSize);
5222
+ return clamp(0, filledChunks * chunkRelativeSize - gapRelativeSize / 2, 100);
5223
+ }
5224
+ return {
5225
+ hasChunks,
5226
+ chunksMaskStyles,
5227
+ snapValueToChunk
5228
+ };
5229
+ }
5230
+
5168
5231
  const makeVProgressLinearProps = propsFactory({
5169
5232
  absolute: Boolean,
5170
5233
  active: {
@@ -5199,6 +5262,7 @@ const makeVProgressLinearProps = propsFactory({
5199
5262
  stream: Boolean,
5200
5263
  striped: Boolean,
5201
5264
  roundedBar: Boolean,
5265
+ ...makeChunksProps(),
5202
5266
  ...makeComponentProps(),
5203
5267
  ...makeLocationProps({
5204
5268
  location: 'top'
@@ -5217,6 +5281,7 @@ const VProgressLinear = genericComponent()({
5217
5281
  let {
5218
5282
  slots
5219
5283
  } = _ref;
5284
+ const root = ref();
5220
5285
  const progress = useProxiedModel(props, 'modelValue');
5221
5286
  const {
5222
5287
  isRtl,
@@ -5258,6 +5323,24 @@ const VProgressLinear = genericComponent()({
5258
5323
  const isReversed = computed(() => isRtl.value !== props.reverse);
5259
5324
  const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
5260
5325
  const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
5326
+ const containerWidth = shallowRef(0);
5327
+ const {
5328
+ hasChunks,
5329
+ chunksMaskStyles,
5330
+ snapValueToChunk
5331
+ } = useChunks(props, containerWidth);
5332
+ useToggleScope(hasChunks, () => {
5333
+ const {
5334
+ resizeRef
5335
+ } = useResizeObserver(entries => containerWidth.value = entries[0].contentRect.width);
5336
+ watchEffect(() => resizeRef.value = root.value);
5337
+ });
5338
+ const bufferWidth = computed(() => {
5339
+ return hasChunks.value ? snapValueToChunk(normalizedBuffer.value) : normalizedBuffer.value;
5340
+ });
5341
+ const barWidth = computed(() => {
5342
+ return hasChunks.value ? snapValueToChunk(normalizedValue.value) : normalizedValue.value;
5343
+ });
5261
5344
  function handleClick(e) {
5262
5345
  if (!intersectionRef.value) return;
5263
5346
  const {
@@ -5268,8 +5351,11 @@ const VProgressLinear = genericComponent()({
5268
5351
  const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
5269
5352
  progress.value = Math.round(value / width * max.value);
5270
5353
  }
5354
+ watchEffect(() => {
5355
+ intersectionRef.value = root.value;
5356
+ });
5271
5357
  useRender(() => createVNode(props.tag, {
5272
- "ref": intersectionRef,
5358
+ "ref": root,
5273
5359
  "class": normalizeClass(['v-progress-linear', {
5274
5360
  'v-progress-linear--absolute': props.absolute,
5275
5361
  'v-progress-linear--active': props.active && isIntersecting.value,
@@ -5284,7 +5370,7 @@ const VProgressLinear = genericComponent()({
5284
5370
  height: props.active ? convertToUnit(height.value) : 0,
5285
5371
  '--v-progress-linear-height': convertToUnit(height.value),
5286
5372
  ...(props.absolute ? locationStyles.value : {})
5287
- }, props.style]),
5373
+ }, chunksMaskStyles.value, props.style]),
5288
5374
  "role": "progressbar",
5289
5375
  "aria-hidden": props.active ? 'false' : 'true',
5290
5376
  "aria-valuemin": "0",
@@ -5314,7 +5400,7 @@ const VProgressLinear = genericComponent()({
5314
5400
  "class": normalizeClass(['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined]),
5315
5401
  "style": normalizeStyle([bufferColorStyles.value, {
5316
5402
  opacity: parseFloat(props.bufferOpacity),
5317
- width: convertToUnit(normalizedBuffer.value, '%')
5403
+ width: convertToUnit(bufferWidth.value, '%')
5318
5404
  }])
5319
5405
  }, null), createVNode(Transition, {
5320
5406
  "name": transition.value
@@ -5322,7 +5408,7 @@ const VProgressLinear = genericComponent()({
5322
5408
  default: () => [!props.indeterminate ? createElementVNode("div", {
5323
5409
  "class": normalizeClass(['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined]),
5324
5410
  "style": normalizeStyle([barColorStyles.value, {
5325
- width: convertToUnit(normalizedValue.value, '%')
5411
+ width: convertToUnit(barWidth.value, '%')
5326
5412
  }])
5327
5413
  }, null) : createElementVNode("div", {
5328
5414
  "class": "v-progress-linear__indeterminate"
@@ -9540,6 +9626,11 @@ const VListItem = genericComponent()({
9540
9626
  const isLink = toRef(() => props.link !== false && link.isLink.value);
9541
9627
  const isSelectable = computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
9542
9628
  const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
9629
+ const role = computed(() => list ? isSelectable.value ? 'option' : 'listitem' : undefined);
9630
+ const ariaSelected = computed(() => {
9631
+ if (!isSelectable.value) return undefined;
9632
+ return root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value;
9633
+ });
9543
9634
  const roundedProps = toRef(() => props.rounded || props.nav);
9544
9635
  const color = toRef(() => props.color ?? props.activeColor);
9545
9636
  const variantProps = toRef(() => ({
@@ -9643,7 +9734,8 @@ const VListItem = genericComponent()({
9643
9734
  }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
9644
9735
  "style": [colorStyles.value, dimensionStyles.value, props.style],
9645
9736
  "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
9646
- "aria-selected": isSelectable.value ? root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value : undefined,
9737
+ "aria-selected": ariaSelected.value,
9738
+ "role": role.value,
9647
9739
  "onClick": onClick,
9648
9740
  "onKeydown": isClickable.value && !isLink.value && onKeyDown
9649
9741
  }, link.linkProps), {
@@ -10145,6 +10237,7 @@ const VList = genericComponent()({
10145
10237
  const activeColor = toRef(() => props.activeColor);
10146
10238
  const baseColor = toRef(() => props.baseColor);
10147
10239
  const color = toRef(() => props.color);
10240
+ const isSelectable = toRef(() => props.selectable || props.activatable);
10148
10241
  createList({
10149
10242
  filterable: props.filterable
10150
10243
  });
@@ -10216,7 +10309,7 @@ const VList = genericComponent()({
10216
10309
  }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class]),
10217
10310
  "style": normalizeStyle([backgroundColorStyles.value, dimensionStyles.value, props.style]),
10218
10311
  "tabindex": props.disabled ? -1 : 0,
10219
- "role": "listbox",
10312
+ "role": isSelectable.value ? 'listbox' : 'list',
10220
10313
  "aria-activedescendant": undefined,
10221
10314
  "onFocusin": onFocusin,
10222
10315
  "onFocusout": onFocusout,
@@ -13286,6 +13379,7 @@ const VSelect = genericComponent()({
13286
13379
  "onKeydown": onListKeydown,
13287
13380
  "onFocusin": onFocusin,
13288
13381
  "tabindex": "-1",
13382
+ "selectable": true,
13289
13383
  "aria-live": "polite",
13290
13384
  "aria-label": `${props.label}-list`,
13291
13385
  "color": props.itemColor ?? props.color
@@ -13905,6 +13999,7 @@ const VAutocomplete = genericComponent()({
13905
13999
  "onFocusin": onFocusin,
13906
14000
  "onFocusout": onFocusout,
13907
14001
  "tabindex": "-1",
14002
+ "selectable": true,
13908
14003
  "aria-live": "polite",
13909
14004
  "color": props.itemColor ?? props.color
13910
14005
  }, listEvents, props.listProps), {
@@ -18992,6 +19087,7 @@ const VCombobox = genericComponent()({
18992
19087
  "selected": selectedValues.value,
18993
19088
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18994
19089
  "onMousedown": e => e.preventDefault(),
19090
+ "selectable": true,
18995
19091
  "onKeydown": onListKeydown,
18996
19092
  "onFocusin": onFocusin,
18997
19093
  "onFocusout": onFocusout,
@@ -24090,6 +24186,42 @@ function appendIfDirectory(path, item) {
24090
24186
  return item.isDirectory ? `${path}/${item.name}` : path;
24091
24187
  }
24092
24188
 
24189
+ // Utilities
24190
+ // Composables
24191
+ const makeFileFilterProps = propsFactory({
24192
+ filterByType: String
24193
+ }, 'file-accept');
24194
+ function useFileFilter(props) {
24195
+ const fileFilter = computed(() => props.filterByType ? createFilter(props.filterByType) : null);
24196
+ function filterAccepted(files) {
24197
+ if (fileFilter.value) {
24198
+ const accepted = files.filter(fileFilter.value);
24199
+ return {
24200
+ accepted,
24201
+ rejected: files.filter(f => !accepted.includes(f))
24202
+ };
24203
+ }
24204
+ return {
24205
+ accepted: files,
24206
+ rejected: []
24207
+ };
24208
+ }
24209
+ return {
24210
+ filterAccepted
24211
+ };
24212
+ }
24213
+ function createFilter(v) {
24214
+ const types = v.split(',').map(x => x.trim().toLowerCase());
24215
+ const extensionsToMatch = types.filter(x => x.startsWith('.'));
24216
+ const wildcards = types.filter(x => x.endsWith('/*'));
24217
+ const typesToMatch = types.filter(x => !extensionsToMatch.includes(x) && !wildcards.includes(x));
24218
+ return file => {
24219
+ const extension = file.name.split('.').at(-1)?.toLowerCase() ?? '';
24220
+ const typeGroup = file.type.split('/').at(0)?.toLowerCase() ?? '';
24221
+ return typesToMatch.includes(file.type) || extensionsToMatch.includes(`.${extension}`) || wildcards.includes(`${typeGroup}/*`);
24222
+ };
24223
+ }
24224
+
24093
24225
  // Types
24094
24226
 
24095
24227
  const makeVFileInputProps = propsFactory({
@@ -24122,6 +24254,7 @@ const makeVFileInputProps = propsFactory({
24122
24254
  return wrapInArray(val).every(v => v != null && typeof v === 'object');
24123
24255
  }
24124
24256
  },
24257
+ ...makeFileFilterProps(),
24125
24258
  ...makeVFieldProps({
24126
24259
  clearable: true
24127
24260
  })
@@ -24134,7 +24267,8 @@ const VFileInput = genericComponent()({
24134
24267
  'click:control': e => true,
24135
24268
  'mousedown:control': e => true,
24136
24269
  'update:focused': focused => true,
24137
- 'update:modelValue': files => true
24270
+ 'update:modelValue': files => true,
24271
+ rejected: files => true
24138
24272
  },
24139
24273
  setup(props, _ref) {
24140
24274
  let {
@@ -24145,6 +24279,9 @@ const VFileInput = genericComponent()({
24145
24279
  const {
24146
24280
  t
24147
24281
  } = useLocale();
24282
+ const {
24283
+ filterAccepted
24284
+ } = useFileFilter(props);
24148
24285
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
24149
24286
  const {
24150
24287
  isFocused,
@@ -24218,14 +24355,38 @@ const VFileInput = genericComponent()({
24218
24355
  e.stopImmediatePropagation();
24219
24356
  isDragging.value = false;
24220
24357
  if (!inputRef.value || !hasFilesOrFolders(e)) return;
24358
+ const allDroppedFiles = await handleDrop(e);
24359
+ selectAccepted(allDroppedFiles);
24360
+ }
24361
+ function onFileSelection(e) {
24362
+ if (!e.target || e.repack) return; // prevent loop
24363
+
24364
+ if (!props.filterByType) {
24365
+ const target = e.target;
24366
+ model.value = [...(target.files ?? [])];
24367
+ } else {
24368
+ selectAccepted([...e.target.files]);
24369
+ }
24370
+ }
24371
+ function selectAccepted(files) {
24221
24372
  const dataTransfer = new DataTransfer();
24222
- for (const file of await handleDrop(e)) {
24373
+ const {
24374
+ accepted,
24375
+ rejected
24376
+ } = filterAccepted(files);
24377
+ if (rejected.length) {
24378
+ emit('rejected', rejected);
24379
+ }
24380
+ for (const file of accepted) {
24223
24381
  dataTransfer.items.add(file);
24224
24382
  }
24225
24383
  inputRef.value.files = dataTransfer.files;
24226
- inputRef.value.dispatchEvent(new Event('change', {
24384
+ model.value = [...dataTransfer.files];
24385
+ const event = new Event('change', {
24227
24386
  bubbles: true
24228
- }));
24387
+ });
24388
+ event.repack = true;
24389
+ inputRef.value.dispatchEvent(event);
24229
24390
  }
24230
24391
  watch(model, newValue => {
24231
24392
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -24242,6 +24403,8 @@ const VFileInput = genericComponent()({
24242
24403
  ...inputProps
24243
24404
  } = VInput.filterProps(props);
24244
24405
  const fieldProps = VField.filterProps(props);
24406
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
24407
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
24245
24408
  return createVNode(VInput, mergeProps({
24246
24409
  "ref": vInputRef,
24247
24410
  "modelValue": props.multiple ? model.value : model.value[0],
@@ -24297,6 +24460,7 @@ const VFileInput = genericComponent()({
24297
24460
  return createElementVNode(Fragment, null, [createElementVNode("input", mergeProps({
24298
24461
  "ref": inputRef,
24299
24462
  "type": "file",
24463
+ "accept": inputAccept,
24300
24464
  "readonly": isReadonly.value,
24301
24465
  "disabled": isDisabled.value,
24302
24466
  "multiple": props.multiple,
@@ -24306,11 +24470,7 @@ const VFileInput = genericComponent()({
24306
24470
  if (isReadonly.value) e.preventDefault();
24307
24471
  onFocus();
24308
24472
  },
24309
- "onChange": e => {
24310
- if (!e.target) return;
24311
- const target = e.target;
24312
- model.value = [...(target.files ?? [])];
24313
- },
24473
+ "onChange": onFileSelection,
24314
24474
  "onDragleave": onDragleave,
24315
24475
  "onFocus": onFocus,
24316
24476
  "onBlur": blur
@@ -30345,51 +30505,48 @@ const VTreeviewChildren = genericComponent()({
30345
30505
  parentIndentLines: props.parentIndentLines,
30346
30506
  variant: props.indentLinesVariant
30347
30507
  });
30348
- function renderItem(itemProps) {
30349
- return createVNode(VTreeviewItem, itemProps, {
30350
- prepend: slotProps => createElementVNode(Fragment, null, [props.selectable && (!children || children && !['leaf', 'single-leaf'].includes(props.selectStrategy)) && createElementVNode("div", null, [createVNode(VCheckboxBtn, {
30351
- "key": item.value,
30352
- "modelValue": slotProps.isSelected,
30353
- "disabled": props.disabled,
30354
- "loading": loading,
30355
- "color": props.selectedColor,
30356
- "density": props.density,
30357
- "indeterminate": slotProps.isIndeterminate,
30358
- "indeterminateIcon": props.indeterminateIcon,
30359
- "falseIcon": props.falseIcon,
30360
- "trueIcon": props.trueIcon,
30361
- "onUpdate:modelValue": v => selectItem(slotProps.select, v),
30362
- "onClick": e => e.stopPropagation(),
30363
- "onKeydown": e => {
30364
- if (!['Enter', 'Space'].includes(e.key)) return;
30365
- e.stopPropagation();
30366
- selectItem(slotProps.select, slotProps.isSelected);
30367
- }
30368
- }, null)]), slots.prepend?.({
30369
- ...slotProps,
30370
- ...treeItemProps,
30371
- item: item.raw,
30372
- internalItem: item
30373
- })]),
30374
- append: slots.append ? slotProps => slots.append?.({
30375
- ...slotProps,
30376
- ...treeItemProps,
30377
- item: item.raw,
30378
- internalItem: item
30379
- }) : undefined,
30380
- title: slots.title ? slotProps => slots.title?.({
30381
- ...slotProps,
30382
- item: item.raw,
30383
- internalItem: item
30384
- }) : undefined,
30385
- subtitle: slots.subtitle ? slotProps => slots.subtitle?.({
30386
- ...slotProps,
30387
- item: item.raw,
30388
- internalItem: item
30389
- }) : undefined,
30390
- $stable: true
30391
- });
30392
- }
30508
+ const slotsWithItem = {
30509
+ prepend: slotProps => createElementVNode(Fragment, null, [props.selectable && (!children || children && !['leaf', 'single-leaf'].includes(props.selectStrategy)) && createElementVNode("div", null, [createVNode(VCheckboxBtn, {
30510
+ "key": item.value,
30511
+ "modelValue": slotProps.isSelected,
30512
+ "disabled": props.disabled,
30513
+ "loading": loading,
30514
+ "color": props.selectedColor,
30515
+ "density": props.density,
30516
+ "indeterminate": slotProps.isIndeterminate,
30517
+ "indeterminateIcon": props.indeterminateIcon,
30518
+ "falseIcon": props.falseIcon,
30519
+ "trueIcon": props.trueIcon,
30520
+ "onUpdate:modelValue": v => selectItem(slotProps.select, v),
30521
+ "onClick": e => e.stopPropagation(),
30522
+ "onKeydown": e => {
30523
+ if (!['Enter', 'Space'].includes(e.key)) return;
30524
+ e.stopPropagation();
30525
+ selectItem(slotProps.select, slotProps.isSelected);
30526
+ }
30527
+ }, null)]), slots.prepend?.({
30528
+ ...slotProps,
30529
+ ...treeItemProps,
30530
+ item: item.raw,
30531
+ internalItem: item
30532
+ })]),
30533
+ append: slots.append ? slotProps => slots.append?.({
30534
+ ...slotProps,
30535
+ ...treeItemProps,
30536
+ item: item.raw,
30537
+ internalItem: item
30538
+ }) : undefined,
30539
+ title: slots.title ? slotProps => slots.title?.({
30540
+ ...slotProps,
30541
+ item: item.raw,
30542
+ internalItem: item
30543
+ }) : undefined,
30544
+ subtitle: slots.subtitle ? slotProps => slots.subtitle?.({
30545
+ ...slotProps,
30546
+ item: item.raw,
30547
+ internalItem: item
30548
+ }) : undefined
30549
+ };
30393
30550
  const treeviewGroupProps = VTreeviewGroup.filterProps(itemProps);
30394
30551
  const treeviewChildrenProps = VTreeviewChildren.filterProps({
30395
30552
  ...props,
@@ -30403,16 +30560,21 @@ const VTreeviewChildren = genericComponent()({
30403
30560
  let {
30404
30561
  props: activatorProps
30405
30562
  } = _ref2;
30406
- return renderItem({
30563
+ const listItemProps = {
30407
30564
  ...itemProps,
30408
30565
  ...activatorProps,
30409
- loading,
30410
- hideActions: props.hideActions,
30411
- indentLines: indentLines.node,
30412
- value: props.returnObject ? item.raw : itemProps.value,
30566
+ value: itemProps?.value,
30413
30567
  onToggleExpand: [() => checkChildren(item), activatorProps.onClick],
30414
30568
  onClick: isClickOnOpen.value ? [() => checkChildren(item), activatorProps.onClick] : () => selectItem(activatorItems.value[index]?.select, !activatorItems.value[index]?.isSelected)
30415
- });
30569
+ };
30570
+ return createVNode(VTreeviewItem, mergeProps({
30571
+ "ref": el => activatorItems.value[index] = el
30572
+ }, listItemProps, {
30573
+ "hideActions": props.hideActions,
30574
+ "indentLines": indentLines.node,
30575
+ "value": props.returnObject ? item.raw : itemProps.value,
30576
+ "loading": loading
30577
+ }), slotsWithItem);
30416
30578
  },
30417
30579
  default: () => createVNode(VTreeviewChildren, mergeProps(treeviewChildrenProps, {
30418
30580
  "items": children,
@@ -30420,8 +30582,7 @@ const VTreeviewChildren = genericComponent()({
30420
30582
  "parentIndentLines": indentLines.children,
30421
30583
  "isLastGroup": nextItemHasChildren,
30422
30584
  "returnObject": props.returnObject
30423
- }), slots),
30424
- $stable: true
30585
+ }), slots)
30425
30586
  }) : renderSlot(slots.item, {
30426
30587
  props: itemProps,
30427
30588
  item: item.raw,
@@ -30437,12 +30598,11 @@ const VTreeviewChildren = genericComponent()({
30437
30598
  props: item.raw
30438
30599
  }, () => createVNode(VListSubheader, item.props, null));
30439
30600
  }
30440
- return renderItem({
30441
- ...itemProps,
30442
- hideActions: props.hideActions,
30443
- indentLines: indentLines.leaf,
30444
- value: props.returnObject ? toRaw(item.raw) : itemProps.value
30445
- });
30601
+ return createVNode(VTreeviewItem, mergeProps(itemProps, {
30602
+ "hideActions": props.hideActions,
30603
+ "indentLines": indentLines.leaf,
30604
+ "value": props.returnObject ? toRaw(item.raw) : itemProps.value
30605
+ }), slotsWithItem);
30446
30606
  });
30447
30607
  });
30448
30608
  }
@@ -30581,14 +30741,13 @@ const VTreeview = genericComponent()({
30581
30741
  "selected": selected.value,
30582
30742
  "onUpdate:selected": $event => selected.value = $event
30583
30743
  }), {
30584
- default: () => createVNode(VTreeviewChildren, mergeProps(treeviewChildrenProps, {
30744
+ default: () => [createVNode(VTreeviewChildren, mergeProps(treeviewChildrenProps, {
30585
30745
  "density": props.density,
30586
30746
  "returnObject": props.returnObject,
30587
30747
  "items": items.value,
30588
30748
  "parentIndentLines": props.indentLines ? [] : undefined,
30589
30749
  "indentLinesVariant": indentLinesVariant
30590
- }), slots),
30591
- $stable: true
30750
+ }), slots)]
30592
30751
  });
30593
30752
  });
30594
30753
  return {};
@@ -31829,6 +31988,7 @@ const makeVFileUploadProps = propsFactory({
31829
31988
  },
31830
31989
  showSize: Boolean,
31831
31990
  name: String,
31991
+ ...makeFileFilterProps(),
31832
31992
  ...makeDelayProps(),
31833
31993
  ...makeDensityProps(),
31834
31994
  ...pick(makeVDividerProps({
@@ -31841,11 +32001,13 @@ const VFileUpload = genericComponent()({
31841
32001
  inheritAttrs: false,
31842
32002
  props: makeVFileUploadProps(),
31843
32003
  emits: {
31844
- 'update:modelValue': files => true
32004
+ 'update:modelValue': files => true,
32005
+ rejected: files => true
31845
32006
  },
31846
32007
  setup(props, _ref) {
31847
32008
  let {
31848
32009
  attrs,
32010
+ emit,
31849
32011
  slots
31850
32012
  } = _ref;
31851
32013
  const {
@@ -31854,6 +32016,9 @@ const VFileUpload = genericComponent()({
31854
32016
  const {
31855
32017
  densityClasses
31856
32018
  } = useDensity(props);
32019
+ const {
32020
+ filterAccepted
32021
+ } = useFileFilter(props);
31857
32022
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
31858
32023
  const isDragging = shallowRef(false);
31859
32024
  const vSheetRef = ref(null);
@@ -31875,14 +32040,38 @@ const VFileUpload = genericComponent()({
31875
32040
  e.stopImmediatePropagation();
31876
32041
  isDragging.value = false;
31877
32042
  if (!inputRef.value) return;
32043
+ const allDroppedFiles = await handleDrop(e);
32044
+ selectAccepted(allDroppedFiles);
32045
+ }
32046
+ function onFileSelection(e) {
32047
+ if (!e.target || e.repack) return; // prevent loop
32048
+
32049
+ if (!props.filterByType) {
32050
+ const target = e.target;
32051
+ model.value = [...(target.files ?? [])];
32052
+ } else {
32053
+ selectAccepted([...e.target.files]);
32054
+ }
32055
+ }
32056
+ function selectAccepted(files) {
31878
32057
  const dataTransfer = new DataTransfer();
31879
- for (const file of await handleDrop(e)) {
32058
+ const {
32059
+ accepted,
32060
+ rejected
32061
+ } = filterAccepted(files);
32062
+ if (rejected.length) {
32063
+ emit('rejected', rejected);
32064
+ }
32065
+ for (const file of accepted) {
31880
32066
  dataTransfer.items.add(file);
31881
32067
  }
31882
32068
  inputRef.value.files = dataTransfer.files;
31883
- inputRef.value.dispatchEvent(new Event('change', {
32069
+ model.value = [...dataTransfer.files];
32070
+ const event = new Event('change', {
31884
32071
  bubbles: true
31885
- }));
32072
+ });
32073
+ event.repack = true;
32074
+ inputRef.value.dispatchEvent(event);
31886
32075
  }
31887
32076
  function onClick() {
31888
32077
  inputRef.value?.click();
@@ -31900,17 +32089,16 @@ const VFileUpload = genericComponent()({
31900
32089
  const cardProps = VSheet.filterProps(props);
31901
32090
  const dividerProps = VDivider.filterProps(props);
31902
32091
  const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
32092
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
32093
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
31903
32094
  const inputNode = createElementVNode("input", mergeProps({
31904
32095
  "ref": inputRef,
31905
32096
  "type": "file",
32097
+ "accept": inputAccept,
31906
32098
  "disabled": props.disabled,
31907
32099
  "multiple": props.multiple,
31908
32100
  "name": props.name,
31909
- "onChange": e => {
31910
- if (!e.target) return;
31911
- const target = e.target;
31912
- model.value = [...(target.files ?? [])];
31913
- }
32101
+ "onChange": onFileSelection
31914
32102
  }, inputAttrs), null);
31915
32103
  return createElementVNode(Fragment, null, [createVNode(VSheet, mergeProps({
31916
32104
  "ref": vSheetRef
@@ -33689,7 +33877,7 @@ function createVuetify$1() {
33689
33877
  };
33690
33878
  });
33691
33879
  }
33692
- const version$1 = "3.9.1-master.2025-07-17";
33880
+ const version$1 = "3.9.2-dev.2025-07-18";
33693
33881
  createVuetify$1.version = version$1;
33694
33882
 
33695
33883
  // Vue's inject() can only be used in setup
@@ -33987,7 +34175,7 @@ var index = /*#__PURE__*/Object.freeze({
33987
34175
 
33988
34176
  /* eslint-disable local-rules/sort-imports */
33989
34177
 
33990
- const version = "3.9.1-master.2025-07-17";
34178
+ const version = "3.9.2-dev.2025-07-18";
33991
34179
 
33992
34180
  /* eslint-disable local-rules/sort-imports */
33993
34181