@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
  */
@@ -5464,6 +5464,69 @@ function useLocation(props) {
5464
5464
  };
5465
5465
  }
5466
5466
 
5467
+ // Utilities
5468
+
5469
+ // Types
5470
+
5471
+ // Composables
5472
+ const makeChunksProps = propsFactory({
5473
+ chunkCount: {
5474
+ type: [Number, String],
5475
+ default: null
5476
+ },
5477
+ chunkWidth: {
5478
+ type: [Number, String],
5479
+ default: null
5480
+ },
5481
+ chunkGap: {
5482
+ type: [Number, String],
5483
+ default: 4
5484
+ }
5485
+ }, 'chunks');
5486
+ function useChunks(props, containerWidth) {
5487
+ const hasChunks = toRef(() => !!props.chunkCount || !!props.chunkWidth);
5488
+ const chunkWidth = computed(() => {
5489
+ const containerSize = toValue(containerWidth);
5490
+ if (!containerSize) {
5491
+ return 0;
5492
+ }
5493
+ if (!props.chunkCount) {
5494
+ return Number(props.chunkWidth);
5495
+ }
5496
+ const count = Number(props.chunkCount);
5497
+ const availableWidth = containerSize - Number(props.chunkGap) * (count - 1);
5498
+ return availableWidth / count;
5499
+ });
5500
+ const chunkGap = toRef(() => Number(props.chunkGap));
5501
+ const chunksMaskStyles = computed(() => {
5502
+ if (!hasChunks.value) {
5503
+ return {};
5504
+ }
5505
+ const chunkGapPx = convertToUnit(chunkGap.value);
5506
+ const chunkWidthPx = convertToUnit(chunkWidth.value);
5507
+ return {
5508
+ maskRepeat: 'repeat-x',
5509
+ maskImage: `linear-gradient(90deg, #000, #000 ${chunkWidthPx}, transparent ${chunkWidthPx}, transparent)`,
5510
+ maskSize: `calc(${chunkWidthPx} + ${chunkGapPx}) 100%`
5511
+ };
5512
+ });
5513
+ function snapValueToChunk(val) {
5514
+ const containerSize = toValue(containerWidth);
5515
+ if (!containerSize) {
5516
+ return val;
5517
+ }
5518
+ const gapRelativeSize = 100 * chunkGap.value / containerSize;
5519
+ const chunkRelativeSize = 100 * (chunkWidth.value + chunkGap.value) / containerSize;
5520
+ const filledChunks = Math.floor((val + gapRelativeSize) / chunkRelativeSize);
5521
+ return clamp(0, filledChunks * chunkRelativeSize - gapRelativeSize / 2, 100);
5522
+ }
5523
+ return {
5524
+ hasChunks,
5525
+ chunksMaskStyles,
5526
+ snapValueToChunk
5527
+ };
5528
+ }
5529
+
5467
5530
  const makeVProgressLinearProps = propsFactory({
5468
5531
  absolute: Boolean,
5469
5532
  active: {
@@ -5498,6 +5561,7 @@ const makeVProgressLinearProps = propsFactory({
5498
5561
  stream: Boolean,
5499
5562
  striped: Boolean,
5500
5563
  roundedBar: Boolean,
5564
+ ...makeChunksProps(),
5501
5565
  ...makeComponentProps(),
5502
5566
  ...makeLocationProps({
5503
5567
  location: 'top'
@@ -5516,6 +5580,7 @@ const VProgressLinear = genericComponent()({
5516
5580
  let {
5517
5581
  slots
5518
5582
  } = _ref;
5583
+ const root = ref();
5519
5584
  const progress = useProxiedModel(props, 'modelValue');
5520
5585
  const {
5521
5586
  isRtl,
@@ -5557,6 +5622,24 @@ const VProgressLinear = genericComponent()({
5557
5622
  const isReversed = computed(() => isRtl.value !== props.reverse);
5558
5623
  const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
5559
5624
  const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
5625
+ const containerWidth = shallowRef(0);
5626
+ const {
5627
+ hasChunks,
5628
+ chunksMaskStyles,
5629
+ snapValueToChunk
5630
+ } = useChunks(props, containerWidth);
5631
+ useToggleScope(hasChunks, () => {
5632
+ const {
5633
+ resizeRef
5634
+ } = useResizeObserver(entries => containerWidth.value = entries[0].contentRect.width);
5635
+ watchEffect(() => resizeRef.value = root.value);
5636
+ });
5637
+ const bufferWidth = computed(() => {
5638
+ return hasChunks.value ? snapValueToChunk(normalizedBuffer.value) : normalizedBuffer.value;
5639
+ });
5640
+ const barWidth = computed(() => {
5641
+ return hasChunks.value ? snapValueToChunk(normalizedValue.value) : normalizedValue.value;
5642
+ });
5560
5643
  function handleClick(e) {
5561
5644
  if (!intersectionRef.value) return;
5562
5645
  const {
@@ -5567,8 +5650,11 @@ const VProgressLinear = genericComponent()({
5567
5650
  const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
5568
5651
  progress.value = Math.round(value / width * max.value);
5569
5652
  }
5653
+ watchEffect(() => {
5654
+ intersectionRef.value = root.value;
5655
+ });
5570
5656
  useRender(() => createVNode(props.tag, {
5571
- "ref": intersectionRef,
5657
+ "ref": root,
5572
5658
  "class": normalizeClass(['v-progress-linear', {
5573
5659
  'v-progress-linear--absolute': props.absolute,
5574
5660
  'v-progress-linear--active': props.active && isIntersecting.value,
@@ -5583,7 +5669,7 @@ const VProgressLinear = genericComponent()({
5583
5669
  height: props.active ? convertToUnit(height.value) : 0,
5584
5670
  '--v-progress-linear-height': convertToUnit(height.value),
5585
5671
  ...(props.absolute ? locationStyles.value : {})
5586
- }, props.style]),
5672
+ }, chunksMaskStyles.value, props.style]),
5587
5673
  "role": "progressbar",
5588
5674
  "aria-hidden": props.active ? 'false' : 'true',
5589
5675
  "aria-valuemin": "0",
@@ -5613,7 +5699,7 @@ const VProgressLinear = genericComponent()({
5613
5699
  "class": normalizeClass(['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined]),
5614
5700
  "style": normalizeStyle([bufferColorStyles.value, {
5615
5701
  opacity: parseFloat(props.bufferOpacity),
5616
- width: convertToUnit(normalizedBuffer.value, '%')
5702
+ width: convertToUnit(bufferWidth.value, '%')
5617
5703
  }])
5618
5704
  }, null), createVNode(Transition, {
5619
5705
  "name": transition.value
@@ -5621,7 +5707,7 @@ const VProgressLinear = genericComponent()({
5621
5707
  default: () => [!props.indeterminate ? createElementVNode("div", {
5622
5708
  "class": normalizeClass(['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined]),
5623
5709
  "style": normalizeStyle([barColorStyles.value, {
5624
- width: convertToUnit(normalizedValue.value, '%')
5710
+ width: convertToUnit(barWidth.value, '%')
5625
5711
  }])
5626
5712
  }, null) : createElementVNode("div", {
5627
5713
  "class": "v-progress-linear__indeterminate"
@@ -9836,6 +9922,11 @@ const VListItem = genericComponent()({
9836
9922
  const isLink = toRef(() => props.link !== false && link.isLink.value);
9837
9923
  const isSelectable = computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
9838
9924
  const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
9925
+ const role = computed(() => list ? isSelectable.value ? 'option' : 'listitem' : undefined);
9926
+ const ariaSelected = computed(() => {
9927
+ if (!isSelectable.value) return undefined;
9928
+ return root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value;
9929
+ });
9839
9930
  const roundedProps = toRef(() => props.rounded || props.nav);
9840
9931
  const color = toRef(() => props.color ?? props.activeColor);
9841
9932
  const variantProps = toRef(() => ({
@@ -9939,7 +10030,8 @@ const VListItem = genericComponent()({
9939
10030
  }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
9940
10031
  "style": [colorStyles.value, dimensionStyles.value, props.style],
9941
10032
  "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
9942
- "aria-selected": isSelectable.value ? root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value : undefined,
10033
+ "aria-selected": ariaSelected.value,
10034
+ "role": role.value,
9943
10035
  "onClick": onClick,
9944
10036
  "onKeydown": isClickable.value && !isLink.value && onKeyDown
9945
10037
  }, link.linkProps), {
@@ -10431,6 +10523,7 @@ const VList = genericComponent()({
10431
10523
  const activeColor = toRef(() => props.activeColor);
10432
10524
  const baseColor = toRef(() => props.baseColor);
10433
10525
  const color = toRef(() => props.color);
10526
+ const isSelectable = toRef(() => props.selectable || props.activatable);
10434
10527
  createList({
10435
10528
  filterable: props.filterable
10436
10529
  });
@@ -10500,7 +10593,7 @@ const VList = genericComponent()({
10500
10593
  }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class]),
10501
10594
  "style": normalizeStyle([backgroundColorStyles.value, dimensionStyles.value, props.style]),
10502
10595
  "tabindex": props.disabled ? -1 : 0,
10503
- "role": "listbox",
10596
+ "role": isSelectable.value ? 'listbox' : 'list',
10504
10597
  "aria-activedescendant": undefined,
10505
10598
  "onFocusin": onFocusin,
10506
10599
  "onFocusout": onFocusout,
@@ -13565,6 +13658,7 @@ const VSelect = genericComponent()({
13565
13658
  "onKeydown": onListKeydown,
13566
13659
  "onFocusin": onFocusin,
13567
13660
  "tabindex": "-1",
13661
+ "selectable": true,
13568
13662
  "aria-live": "polite",
13569
13663
  "aria-label": `${props.label}-list`,
13570
13664
  "color": props.itemColor ?? props.color
@@ -14184,6 +14278,7 @@ const VAutocomplete = genericComponent()({
14184
14278
  "onFocusin": onFocusin,
14185
14279
  "onFocusout": onFocusout,
14186
14280
  "tabindex": "-1",
14281
+ "selectable": true,
14187
14282
  "aria-live": "polite",
14188
14283
  "color": props.itemColor ?? props.color
14189
14284
  }, listEvents, props.listProps), {
@@ -19271,6 +19366,7 @@ const VCombobox = genericComponent()({
19271
19366
  "selected": selectedValues.value,
19272
19367
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
19273
19368
  "onMousedown": e => e.preventDefault(),
19369
+ "selectable": true,
19274
19370
  "onKeydown": onListKeydown,
19275
19371
  "onFocusin": onFocusin,
19276
19372
  "onFocusout": onFocusout,
@@ -24369,6 +24465,42 @@ function appendIfDirectory(path, item) {
24369
24465
  return item.isDirectory ? `${path}/${item.name}` : path;
24370
24466
  }
24371
24467
 
24468
+ // Utilities
24469
+ // Composables
24470
+ const makeFileFilterProps = propsFactory({
24471
+ filterByType: String
24472
+ }, 'file-accept');
24473
+ function useFileFilter(props) {
24474
+ const fileFilter = computed(() => props.filterByType ? createFilter(props.filterByType) : null);
24475
+ function filterAccepted(files) {
24476
+ if (fileFilter.value) {
24477
+ const accepted = files.filter(fileFilter.value);
24478
+ return {
24479
+ accepted,
24480
+ rejected: files.filter(f => !accepted.includes(f))
24481
+ };
24482
+ }
24483
+ return {
24484
+ accepted: files,
24485
+ rejected: []
24486
+ };
24487
+ }
24488
+ return {
24489
+ filterAccepted
24490
+ };
24491
+ }
24492
+ function createFilter(v) {
24493
+ const types = v.split(',').map(x => x.trim().toLowerCase());
24494
+ const extensionsToMatch = types.filter(x => x.startsWith('.'));
24495
+ const wildcards = types.filter(x => x.endsWith('/*'));
24496
+ const typesToMatch = types.filter(x => !extensionsToMatch.includes(x) && !wildcards.includes(x));
24497
+ return file => {
24498
+ const extension = file.name.split('.').at(-1)?.toLowerCase() ?? '';
24499
+ const typeGroup = file.type.split('/').at(0)?.toLowerCase() ?? '';
24500
+ return typesToMatch.includes(file.type) || extensionsToMatch.includes(`.${extension}`) || wildcards.includes(`${typeGroup}/*`);
24501
+ };
24502
+ }
24503
+
24372
24504
  // Types
24373
24505
 
24374
24506
  const makeVFileInputProps = propsFactory({
@@ -24401,6 +24533,7 @@ const makeVFileInputProps = propsFactory({
24401
24533
  return wrapInArray(val).every(v => v != null && typeof v === 'object');
24402
24534
  }
24403
24535
  },
24536
+ ...makeFileFilterProps(),
24404
24537
  ...makeVFieldProps({
24405
24538
  clearable: true
24406
24539
  })
@@ -24413,7 +24546,8 @@ const VFileInput = genericComponent()({
24413
24546
  'click:control': e => true,
24414
24547
  'mousedown:control': e => true,
24415
24548
  'update:focused': focused => true,
24416
- 'update:modelValue': files => true
24549
+ 'update:modelValue': files => true,
24550
+ rejected: files => true
24417
24551
  },
24418
24552
  setup(props, _ref) {
24419
24553
  let {
@@ -24424,6 +24558,9 @@ const VFileInput = genericComponent()({
24424
24558
  const {
24425
24559
  t
24426
24560
  } = useLocale();
24561
+ const {
24562
+ filterAccepted
24563
+ } = useFileFilter(props);
24427
24564
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
24428
24565
  const {
24429
24566
  isFocused,
@@ -24497,14 +24634,38 @@ const VFileInput = genericComponent()({
24497
24634
  e.stopImmediatePropagation();
24498
24635
  isDragging.value = false;
24499
24636
  if (!inputRef.value || !hasFilesOrFolders(e)) return;
24637
+ const allDroppedFiles = await handleDrop(e);
24638
+ selectAccepted(allDroppedFiles);
24639
+ }
24640
+ function onFileSelection(e) {
24641
+ if (!e.target || e.repack) return; // prevent loop
24642
+
24643
+ if (!props.filterByType) {
24644
+ const target = e.target;
24645
+ model.value = [...(target.files ?? [])];
24646
+ } else {
24647
+ selectAccepted([...e.target.files]);
24648
+ }
24649
+ }
24650
+ function selectAccepted(files) {
24500
24651
  const dataTransfer = new DataTransfer();
24501
- for (const file of await handleDrop(e)) {
24652
+ const {
24653
+ accepted,
24654
+ rejected
24655
+ } = filterAccepted(files);
24656
+ if (rejected.length) {
24657
+ emit('rejected', rejected);
24658
+ }
24659
+ for (const file of accepted) {
24502
24660
  dataTransfer.items.add(file);
24503
24661
  }
24504
24662
  inputRef.value.files = dataTransfer.files;
24505
- inputRef.value.dispatchEvent(new Event('change', {
24663
+ model.value = [...dataTransfer.files];
24664
+ const event = new Event('change', {
24506
24665
  bubbles: true
24507
- }));
24666
+ });
24667
+ event.repack = true;
24668
+ inputRef.value.dispatchEvent(event);
24508
24669
  }
24509
24670
  watch(model, newValue => {
24510
24671
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -24521,6 +24682,8 @@ const VFileInput = genericComponent()({
24521
24682
  ...inputProps
24522
24683
  } = VInput.filterProps(props);
24523
24684
  const fieldProps = VField.filterProps(props);
24685
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
24686
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
24524
24687
  return createVNode(VInput, mergeProps({
24525
24688
  "ref": vInputRef,
24526
24689
  "modelValue": props.multiple ? model.value : model.value[0],
@@ -24574,6 +24737,7 @@ const VFileInput = genericComponent()({
24574
24737
  return createElementVNode(Fragment, null, [createElementVNode("input", mergeProps({
24575
24738
  "ref": inputRef,
24576
24739
  "type": "file",
24740
+ "accept": inputAccept,
24577
24741
  "readonly": isReadonly.value,
24578
24742
  "disabled": isDisabled.value,
24579
24743
  "multiple": props.multiple,
@@ -24583,11 +24747,7 @@ const VFileInput = genericComponent()({
24583
24747
  if (isReadonly.value) e.preventDefault();
24584
24748
  onFocus();
24585
24749
  },
24586
- "onChange": e => {
24587
- if (!e.target) return;
24588
- const target = e.target;
24589
- model.value = [...(target.files ?? [])];
24590
- },
24750
+ "onChange": onFileSelection,
24591
24751
  "onDragleave": onDragleave,
24592
24752
  "onFocus": onFocus,
24593
24753
  "onBlur": blur
@@ -31382,7 +31542,7 @@ function createVuetify$1() {
31382
31542
  };
31383
31543
  });
31384
31544
  }
31385
- const version$1 = "3.9.0-dev.2025-07-08";
31545
+ const version$1 = "3.9.0-dev.2025-07-16";
31386
31546
  createVuetify$1.version = version$1;
31387
31547
 
31388
31548
  // Vue's inject() can only be used in setup
@@ -31407,7 +31567,7 @@ const createVuetify = function () {
31407
31567
  ...options
31408
31568
  });
31409
31569
  };
31410
- const version = "3.9.0-dev.2025-07-08";
31570
+ const version = "3.9.0-dev.2025-07-16";
31411
31571
  createVuetify.version = version;
31412
31572
 
31413
31573
  export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useHotkey, useLayout, useLocale, useRtl, useTheme, version };