@vuetify/nightly 3.9.2-master.2025-07-28 → 3.9.3-dev.2025-07-30

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 (206) hide show
  1. package/CHANGELOG.md +8 -53
  2. package/dist/json/attributes.json +3804 -3784
  3. package/dist/json/importMap-labs.json +28 -28
  4. package/dist/json/importMap.json +192 -192
  5. package/dist/json/tags.json +5 -0
  6. package/dist/json/web-types.json +6986 -6916
  7. package/dist/vuetify-labs.cjs +272 -44
  8. package/dist/vuetify-labs.css +5500 -5503
  9. package/dist/vuetify-labs.d.ts +132 -69
  10. package/dist/vuetify-labs.esm.js +272 -44
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +272 -44
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +234 -35
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +4797 -4800
  17. package/dist/vuetify.d.ts +122 -69
  18. package/dist/vuetify.esm.js +234 -35
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +234 -35
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +792 -768
  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 +11 -6
  28. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  29. package/lib/components/VDatePicker/VDatePickerControls.js +8 -1
  30. package/lib/components/VDatePicker/VDatePickerControls.js.map +1 -1
  31. package/lib/components/VDatePicker/VDatePickerMonth.js +11 -0
  32. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  33. package/lib/components/VDatePicker/VDatePickerMonths.js +3 -0
  34. package/lib/components/VDatePicker/VDatePickerMonths.js.map +1 -1
  35. package/lib/components/VFileInput/VFileInput.d.ts +15 -0
  36. package/lib/components/VFileInput/VFileInput.js +38 -9
  37. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  38. package/lib/components/VList/VList.js +2 -1
  39. package/lib/components/VList/VList.js.map +1 -1
  40. package/lib/components/VList/VListChildren.js +3 -4
  41. package/lib/components/VList/VListChildren.js.map +1 -1
  42. package/lib/components/VList/VListItem.js +7 -1
  43. package/lib/components/VList/VListItem.js.map +1 -1
  44. package/lib/components/VProgressLinear/VProgressLinear.css +1 -1
  45. package/lib/components/VProgressLinear/VProgressLinear.d.ts +75 -0
  46. package/lib/components/VProgressLinear/VProgressLinear.js +32 -6
  47. package/lib/components/VProgressLinear/VProgressLinear.js.map +1 -1
  48. package/lib/components/VProgressLinear/VProgressLinear.sass +1 -1
  49. package/lib/components/VProgressLinear/chunks.d.ts +55 -0
  50. package/lib/components/VProgressLinear/chunks.js +62 -0
  51. package/lib/components/VProgressLinear/chunks.js.map +1 -0
  52. package/lib/components/VSelect/VSelect.js +1 -0
  53. package/lib/components/VSelect/VSelect.js.map +1 -1
  54. package/lib/components/VSlider/VSliderThumb.css +9 -14
  55. package/lib/components/VSlider/VSliderThumb.js +13 -7
  56. package/lib/components/VSlider/VSliderThumb.js.map +1 -1
  57. package/lib/components/VSlider/VSliderThumb.sass +9 -14
  58. package/lib/components/VSlider/slider.d.ts +1 -0
  59. package/lib/components/VSlider/slider.js +2 -0
  60. package/lib/components/VSlider/slider.js.map +1 -1
  61. package/lib/composables/fileFilter.d.ts +18 -0
  62. package/lib/composables/fileFilter.js +38 -0
  63. package/lib/composables/fileFilter.js.map +1 -0
  64. package/lib/composables/theme.d.ts +1 -0
  65. package/lib/composables/theme.js +3 -1
  66. package/lib/composables/theme.js.map +1 -1
  67. package/lib/directives/ripple/index.js +2 -2
  68. package/lib/directives/ripple/index.js.map +1 -1
  69. package/lib/entry-bundler.js +1 -1
  70. package/lib/entry-bundler.js.map +1 -1
  71. package/lib/framework.d.ts +70 -69
  72. package/lib/framework.js +1 -1
  73. package/lib/framework.js.map +1 -1
  74. package/lib/labs/VFileUpload/VFileUpload.d.ts +15 -0
  75. package/lib/labs/VFileUpload/VFileUpload.js +39 -9
  76. package/lib/labs/VFileUpload/VFileUpload.js.map +1 -1
  77. package/lib/locale/af.d.ts +7 -0
  78. package/lib/locale/af.js +7 -0
  79. package/lib/locale/af.js.map +1 -1
  80. package/lib/locale/ar.d.ts +7 -0
  81. package/lib/locale/ar.js +13 -6
  82. package/lib/locale/ar.js.map +1 -1
  83. package/lib/locale/az.d.ts +7 -0
  84. package/lib/locale/az.js +7 -0
  85. package/lib/locale/az.js.map +1 -1
  86. package/lib/locale/bg.d.ts +7 -0
  87. package/lib/locale/bg.js +7 -0
  88. package/lib/locale/bg.js.map +1 -1
  89. package/lib/locale/ca.d.ts +7 -0
  90. package/lib/locale/ca.js +7 -0
  91. package/lib/locale/ca.js.map +1 -1
  92. package/lib/locale/ckb.d.ts +7 -0
  93. package/lib/locale/ckb.js +7 -0
  94. package/lib/locale/ckb.js.map +1 -1
  95. package/lib/locale/cs.d.ts +7 -0
  96. package/lib/locale/cs.js +7 -0
  97. package/lib/locale/cs.js.map +1 -1
  98. package/lib/locale/da.d.ts +7 -0
  99. package/lib/locale/da.js +7 -0
  100. package/lib/locale/da.js.map +1 -1
  101. package/lib/locale/de.d.ts +7 -0
  102. package/lib/locale/de.js +7 -0
  103. package/lib/locale/de.js.map +1 -1
  104. package/lib/locale/el.d.ts +7 -0
  105. package/lib/locale/el.js +7 -0
  106. package/lib/locale/el.js.map +1 -1
  107. package/lib/locale/en.d.ts +7 -0
  108. package/lib/locale/en.js +8 -0
  109. package/lib/locale/en.js.map +1 -1
  110. package/lib/locale/es.d.ts +7 -0
  111. package/lib/locale/es.js +7 -0
  112. package/lib/locale/es.js.map +1 -1
  113. package/lib/locale/et.d.ts +7 -0
  114. package/lib/locale/et.js +7 -0
  115. package/lib/locale/et.js.map +1 -1
  116. package/lib/locale/fa.d.ts +7 -0
  117. package/lib/locale/fa.js +7 -0
  118. package/lib/locale/fa.js.map +1 -1
  119. package/lib/locale/fi.d.ts +7 -0
  120. package/lib/locale/fi.js +7 -0
  121. package/lib/locale/fi.js.map +1 -1
  122. package/lib/locale/fr.d.ts +7 -0
  123. package/lib/locale/fr.js +7 -0
  124. package/lib/locale/fr.js.map +1 -1
  125. package/lib/locale/he.d.ts +7 -0
  126. package/lib/locale/he.js +7 -0
  127. package/lib/locale/he.js.map +1 -1
  128. package/lib/locale/hr.d.ts +7 -0
  129. package/lib/locale/hr.js +7 -0
  130. package/lib/locale/hr.js.map +1 -1
  131. package/lib/locale/hu.d.ts +7 -0
  132. package/lib/locale/hu.js +7 -0
  133. package/lib/locale/hu.js.map +1 -1
  134. package/lib/locale/id.d.ts +7 -0
  135. package/lib/locale/id.js +7 -0
  136. package/lib/locale/id.js.map +1 -1
  137. package/lib/locale/it.d.ts +7 -0
  138. package/lib/locale/it.js +7 -0
  139. package/lib/locale/it.js.map +1 -1
  140. package/lib/locale/ja.d.ts +7 -0
  141. package/lib/locale/ja.js +7 -0
  142. package/lib/locale/ja.js.map +1 -1
  143. package/lib/locale/km.d.ts +7 -0
  144. package/lib/locale/km.js +7 -0
  145. package/lib/locale/km.js.map +1 -1
  146. package/lib/locale/ko.d.ts +7 -0
  147. package/lib/locale/ko.js +7 -0
  148. package/lib/locale/ko.js.map +1 -1
  149. package/lib/locale/lt.d.ts +7 -0
  150. package/lib/locale/lt.js +7 -0
  151. package/lib/locale/lt.js.map +1 -1
  152. package/lib/locale/lv.d.ts +7 -0
  153. package/lib/locale/lv.js +7 -0
  154. package/lib/locale/lv.js.map +1 -1
  155. package/lib/locale/nl.d.ts +7 -0
  156. package/lib/locale/nl.js +7 -0
  157. package/lib/locale/nl.js.map +1 -1
  158. package/lib/locale/no.d.ts +7 -0
  159. package/lib/locale/no.js +7 -0
  160. package/lib/locale/no.js.map +1 -1
  161. package/lib/locale/pl.d.ts +7 -0
  162. package/lib/locale/pl.js +7 -0
  163. package/lib/locale/pl.js.map +1 -1
  164. package/lib/locale/pt.d.ts +7 -0
  165. package/lib/locale/pt.js +7 -0
  166. package/lib/locale/pt.js.map +1 -1
  167. package/lib/locale/ro.d.ts +7 -0
  168. package/lib/locale/ro.js +7 -0
  169. package/lib/locale/ro.js.map +1 -1
  170. package/lib/locale/ru.d.ts +7 -0
  171. package/lib/locale/ru.js +7 -0
  172. package/lib/locale/ru.js.map +1 -1
  173. package/lib/locale/sk.d.ts +7 -0
  174. package/lib/locale/sk.js +7 -0
  175. package/lib/locale/sk.js.map +1 -1
  176. package/lib/locale/sl.d.ts +7 -0
  177. package/lib/locale/sl.js +7 -0
  178. package/lib/locale/sl.js.map +1 -1
  179. package/lib/locale/sr-Cyrl.d.ts +7 -0
  180. package/lib/locale/sr-Cyrl.js +7 -0
  181. package/lib/locale/sr-Cyrl.js.map +1 -1
  182. package/lib/locale/sr-Latn.d.ts +7 -0
  183. package/lib/locale/sr-Latn.js +7 -0
  184. package/lib/locale/sr-Latn.js.map +1 -1
  185. package/lib/locale/sv.d.ts +7 -0
  186. package/lib/locale/sv.js +7 -0
  187. package/lib/locale/sv.js.map +1 -1
  188. package/lib/locale/th.d.ts +7 -0
  189. package/lib/locale/th.js +7 -0
  190. package/lib/locale/th.js.map +1 -1
  191. package/lib/locale/tr.d.ts +7 -0
  192. package/lib/locale/tr.js +7 -0
  193. package/lib/locale/tr.js.map +1 -1
  194. package/lib/locale/uk.d.ts +7 -0
  195. package/lib/locale/uk.js +7 -0
  196. package/lib/locale/uk.js.map +1 -1
  197. package/lib/locale/vi.d.ts +7 -0
  198. package/lib/locale/vi.js +7 -0
  199. package/lib/locale/vi.js.map +1 -1
  200. package/lib/locale/zh-Hans.d.ts +7 -0
  201. package/lib/locale/zh-Hans.js +7 -0
  202. package/lib/locale/zh-Hans.js.map +1 -1
  203. package/lib/locale/zh-Hant.d.ts +7 -0
  204. package/lib/locale/zh-Hant.js +7 -0
  205. package/lib/locale/zh-Hant.js.map +1 -1
  206. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.9.2-master.2025-07-28
2
+ * Vuetify v3.9.3-dev.2025-07-30
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -2149,6 +2149,14 @@
2149
2149
  header: 'Enter date',
2150
2150
  input: {
2151
2151
  placeholder: 'Enter date'
2152
+ },
2153
+ ariaLabel: {
2154
+ previousMonth: 'Previous month',
2155
+ nextMonth: 'Next month',
2156
+ selectYear: 'Select year',
2157
+ selectDate: '{0}',
2158
+ // Full date format
2159
+ currentDate: 'Today, {0}'
2152
2160
  }
2153
2161
  },
2154
2162
  noDataText: 'No data available',
@@ -2687,6 +2695,7 @@
2687
2695
  return acc;
2688
2696
  });
2689
2697
  const current = vue.toRef(() => computedThemes.value[name.value]);
2698
+ const isSystem = vue.toRef(() => _name.value === 'system');
2690
2699
  const styles = vue.computed(() => {
2691
2700
  const lines = [];
2692
2701
  const important = parsedOptions.unimportant ? '' : ' !important';
@@ -2774,7 +2783,7 @@
2774
2783
  }
2775
2784
  }
2776
2785
  function change(themeName) {
2777
- if (!themeNames.value.includes(themeName)) {
2786
+ if (themeName !== 'system' && !themeNames.value.includes(themeName)) {
2778
2787
  consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2779
2788
  return;
2780
2789
  }
@@ -2807,6 +2816,7 @@
2807
2816
  cycle,
2808
2817
  toggle,
2809
2818
  isDisabled: parsedOptions.isDisabled,
2819
+ isSystem,
2810
2820
  name,
2811
2821
  themes,
2812
2822
  current,
@@ -5246,6 +5256,69 @@
5246
5256
  };
5247
5257
  }
5248
5258
 
5259
+ // Utilities
5260
+
5261
+ // Types
5262
+
5263
+ // Composables
5264
+ const makeChunksProps = propsFactory({
5265
+ chunkCount: {
5266
+ type: [Number, String],
5267
+ default: null
5268
+ },
5269
+ chunkWidth: {
5270
+ type: [Number, String],
5271
+ default: null
5272
+ },
5273
+ chunkGap: {
5274
+ type: [Number, String],
5275
+ default: 4
5276
+ }
5277
+ }, 'chunks');
5278
+ function useChunks(props, containerWidth) {
5279
+ const hasChunks = vue.toRef(() => !!props.chunkCount || !!props.chunkWidth);
5280
+ const chunkWidth = vue.computed(() => {
5281
+ const containerSize = vue.toValue(containerWidth);
5282
+ if (!containerSize) {
5283
+ return 0;
5284
+ }
5285
+ if (!props.chunkCount) {
5286
+ return Number(props.chunkWidth);
5287
+ }
5288
+ const count = Number(props.chunkCount);
5289
+ const availableWidth = containerSize - Number(props.chunkGap) * (count - 1);
5290
+ return availableWidth / count;
5291
+ });
5292
+ const chunkGap = vue.toRef(() => Number(props.chunkGap));
5293
+ const chunksMaskStyles = vue.computed(() => {
5294
+ if (!hasChunks.value) {
5295
+ return {};
5296
+ }
5297
+ const chunkGapPx = convertToUnit(chunkGap.value);
5298
+ const chunkWidthPx = convertToUnit(chunkWidth.value);
5299
+ return {
5300
+ maskRepeat: 'repeat-x',
5301
+ maskImage: `linear-gradient(90deg, #000, #000 ${chunkWidthPx}, transparent ${chunkWidthPx}, transparent)`,
5302
+ maskSize: `calc(${chunkWidthPx} + ${chunkGapPx}) 100%`
5303
+ };
5304
+ });
5305
+ function snapValueToChunk(val) {
5306
+ const containerSize = vue.toValue(containerWidth);
5307
+ if (!containerSize) {
5308
+ return val;
5309
+ }
5310
+ const gapRelativeSize = 100 * chunkGap.value / containerSize;
5311
+ const chunkRelativeSize = 100 * (chunkWidth.value + chunkGap.value) / containerSize;
5312
+ const filledChunks = Math.floor((val + gapRelativeSize) / chunkRelativeSize);
5313
+ return clamp(0, filledChunks * chunkRelativeSize - gapRelativeSize / 2, 100);
5314
+ }
5315
+ return {
5316
+ hasChunks,
5317
+ chunksMaskStyles,
5318
+ snapValueToChunk
5319
+ };
5320
+ }
5321
+
5249
5322
  const makeVProgressLinearProps = propsFactory({
5250
5323
  absolute: Boolean,
5251
5324
  active: {
@@ -5280,6 +5353,7 @@
5280
5353
  stream: Boolean,
5281
5354
  striped: Boolean,
5282
5355
  roundedBar: Boolean,
5356
+ ...makeChunksProps(),
5283
5357
  ...makeComponentProps(),
5284
5358
  ...makeLocationProps({
5285
5359
  location: 'top'
@@ -5298,6 +5372,7 @@
5298
5372
  let {
5299
5373
  slots
5300
5374
  } = _ref;
5375
+ const root = vue.ref();
5301
5376
  const progress = useProxiedModel(props, 'modelValue');
5302
5377
  const {
5303
5378
  isRtl,
@@ -5339,6 +5414,24 @@
5339
5414
  const isReversed = vue.computed(() => isRtl.value !== props.reverse);
5340
5415
  const transition = vue.computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
5341
5416
  const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
5417
+ const containerWidth = vue.shallowRef(0);
5418
+ const {
5419
+ hasChunks,
5420
+ chunksMaskStyles,
5421
+ snapValueToChunk
5422
+ } = useChunks(props, containerWidth);
5423
+ useToggleScope(hasChunks, () => {
5424
+ const {
5425
+ resizeRef
5426
+ } = useResizeObserver(entries => containerWidth.value = entries[0].contentRect.width);
5427
+ vue.watchEffect(() => resizeRef.value = root.value);
5428
+ });
5429
+ const bufferWidth = vue.computed(() => {
5430
+ return hasChunks.value ? snapValueToChunk(normalizedBuffer.value) : normalizedBuffer.value;
5431
+ });
5432
+ const barWidth = vue.computed(() => {
5433
+ return hasChunks.value ? snapValueToChunk(normalizedValue.value) : normalizedValue.value;
5434
+ });
5342
5435
  function handleClick(e) {
5343
5436
  if (!intersectionRef.value) return;
5344
5437
  const {
@@ -5349,8 +5442,11 @@
5349
5442
  const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
5350
5443
  progress.value = Math.round(value / width * max.value);
5351
5444
  }
5445
+ vue.watchEffect(() => {
5446
+ intersectionRef.value = root.value;
5447
+ });
5352
5448
  useRender(() => vue.createVNode(props.tag, {
5353
- "ref": intersectionRef,
5449
+ "ref": root,
5354
5450
  "class": vue.normalizeClass(['v-progress-linear', {
5355
5451
  'v-progress-linear--absolute': props.absolute,
5356
5452
  'v-progress-linear--active': props.active && isIntersecting.value,
@@ -5366,7 +5462,7 @@
5366
5462
  height: props.active ? convertToUnit(height.value) : 0,
5367
5463
  '--v-progress-linear-height': convertToUnit(height.value),
5368
5464
  ...(props.absolute ? locationStyles.value : {})
5369
- }, props.style]),
5465
+ }, chunksMaskStyles.value, props.style]),
5370
5466
  "role": "progressbar",
5371
5467
  "aria-hidden": props.active ? 'false' : 'true',
5372
5468
  "aria-valuemin": "0",
@@ -5396,7 +5492,7 @@
5396
5492
  "class": vue.normalizeClass(['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined]),
5397
5493
  "style": vue.normalizeStyle([bufferColorStyles.value, {
5398
5494
  opacity: parseFloat(props.bufferOpacity),
5399
- width: convertToUnit(normalizedBuffer.value, '%')
5495
+ width: convertToUnit(bufferWidth.value, '%')
5400
5496
  }])
5401
5497
  }, null), vue.createVNode(vue.Transition, {
5402
5498
  "name": transition.value
@@ -5404,7 +5500,7 @@
5404
5500
  default: () => [!props.indeterminate ? vue.createElementVNode("div", {
5405
5501
  "class": vue.normalizeClass(['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined]),
5406
5502
  "style": vue.normalizeStyle([barColorStyles.value, {
5407
- width: convertToUnit(normalizedValue.value, '%')
5503
+ width: convertToUnit(barWidth.value, '%')
5408
5504
  }])
5409
5505
  }, null) : vue.createElementVNode("div", {
5410
5506
  "class": "v-progress-linear__indeterminate"
@@ -5687,8 +5783,8 @@
5687
5783
  if (!el?._ripple?.enabled) return;
5688
5784
  const ripples = el.getElementsByClassName('v-ripple__animation');
5689
5785
  if (ripples.length === 0) return;
5690
- const animation = ripples[ripples.length - 1];
5691
- if (animation.dataset.isHiding) return;else animation.dataset.isHiding = 'true';
5786
+ const animation = Array.from(ripples).findLast(ripple => !ripple.dataset.isHiding);
5787
+ if (!animation) return;else animation.dataset.isHiding = 'true';
5692
5788
  const diff = performance.now() - Number(animation.dataset.activated);
5693
5789
  const delay = Math.max(250 - diff, 0);
5694
5790
  setTimeout(() => {
@@ -9608,6 +9704,11 @@
9608
9704
  const isLink = vue.toRef(() => props.link !== false && link.isLink.value);
9609
9705
  const isSelectable = vue.computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
9610
9706
  const isClickable = vue.computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
9707
+ const role = vue.computed(() => list ? isSelectable.value ? 'option' : 'listitem' : undefined);
9708
+ const ariaSelected = vue.computed(() => {
9709
+ if (!isSelectable.value) return undefined;
9710
+ return root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value;
9711
+ });
9611
9712
  const roundedProps = vue.toRef(() => props.rounded || props.nav);
9612
9713
  const color = vue.toRef(() => props.color ?? props.activeColor);
9613
9714
  const variantProps = vue.toRef(() => ({
@@ -9711,7 +9812,8 @@
9711
9812
  }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
9712
9813
  "style": [colorStyles.value, dimensionStyles.value, props.style],
9713
9814
  "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
9714
- "aria-selected": isSelectable.value ? root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value : undefined,
9815
+ "aria-selected": ariaSelected.value,
9816
+ "role": role.value,
9715
9817
  "onClick": onClick,
9716
9818
  "onKeydown": isClickable.value && !isLink.value && onKeyDown
9717
9819
  }, link.linkProps), {
@@ -9906,11 +10008,9 @@
9906
10008
  let {
9907
10009
  props: activatorProps
9908
10010
  } = _ref3;
9909
- const listItemProps = {
9910
- ...itemProps,
9911
- ...activatorProps,
10011
+ const listItemProps = vue.mergeProps(itemProps, activatorProps, {
9912
10012
  value: props.returnObject ? item : itemProps.value
9913
- };
10013
+ });
9914
10014
  return slots.header ? slots.header({
9915
10015
  props: listItemProps
9916
10016
  }) : vue.createVNode(VListItem, listItemProps, slotsWithItem);
@@ -10213,6 +10313,7 @@
10213
10313
  const activeColor = vue.toRef(() => props.activeColor);
10214
10314
  const baseColor = vue.toRef(() => props.baseColor);
10215
10315
  const color = vue.toRef(() => props.color);
10316
+ const isSelectable = vue.toRef(() => props.selectable || props.activatable);
10216
10317
  createList({
10217
10318
  filterable: props.filterable
10218
10319
  });
@@ -10284,7 +10385,7 @@
10284
10385
  }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class]),
10285
10386
  "style": vue.normalizeStyle([backgroundColorStyles.value, dimensionStyles.value, props.style]),
10286
10387
  "tabindex": props.disabled ? -1 : 0,
10287
- "role": "listbox",
10388
+ "role": isSelectable.value ? 'listbox' : 'list',
10288
10389
  "aria-activedescendant": undefined,
10289
10390
  "onFocusin": onFocusin,
10290
10391
  "onFocusout": onFocusout,
@@ -13363,6 +13464,7 @@
13363
13464
  "onKeydown": onListKeydown,
13364
13465
  "onFocusin": onFocusin,
13365
13466
  "tabindex": "-1",
13467
+ "selectable": true,
13366
13468
  "aria-live": "polite",
13367
13469
  "aria-label": `${props.label}-list`,
13368
13470
  "color": props.itemColor ?? props.color
@@ -13982,6 +14084,7 @@
13982
14084
  "onFocusin": onFocusin,
13983
14085
  "onFocusout": onFocusout,
13984
14086
  "tabindex": "-1",
14087
+ "selectable": true,
13985
14088
  "aria-live": "polite",
13986
14089
  "color": props.itemColor ?? props.color
13987
14090
  }, listEvents, props.listProps), {
@@ -16314,6 +16417,7 @@
16314
16417
  const numTicks = vue.computed(() => (max.value - min.value) / step.value);
16315
16418
  const disabled = vue.toRef(() => props.disabled);
16316
16419
  const thumbColor = vue.computed(() => props.error || props.disabled ? undefined : props.thumbColor ?? props.color);
16420
+ const thumbLabelColor = vue.computed(() => props.error || props.disabled ? undefined : props.thumbColor);
16317
16421
  const trackColor = vue.computed(() => props.error || props.disabled ? undefined : props.trackColor ?? props.color);
16318
16422
  const trackFillColor = vue.computed(() => props.error || props.disabled ? undefined : props.trackFillColor ?? props.color);
16319
16423
  const mousePressed = vue.shallowRef(false);
@@ -16471,6 +16575,7 @@
16471
16575
  step,
16472
16576
  thumbSize,
16473
16577
  thumbColor,
16578
+ thumbLabelColor,
16474
16579
  thumbLabel: vue.toRef(() => props.thumbLabel),
16475
16580
  ticks: vue.toRef(() => props.ticks),
16476
16581
  tickSize,
@@ -16536,6 +16641,7 @@
16536
16641
  min,
16537
16642
  max,
16538
16643
  thumbColor,
16644
+ thumbLabelColor,
16539
16645
  step,
16540
16646
  disabled,
16541
16647
  thumbSize,
@@ -16557,6 +16663,10 @@
16557
16663
  textColorClasses,
16558
16664
  textColorStyles
16559
16665
  } = useTextColor(thumbColor);
16666
+ const {
16667
+ backgroundColorClasses,
16668
+ backgroundColorStyles
16669
+ } = useBackgroundColor(thumbLabelColor);
16560
16670
  const {
16561
16671
  pageup,
16562
16672
  pagedown,
@@ -16622,9 +16732,7 @@
16622
16732
  "onKeydown": !readonly.value ? onKeydown : undefined
16623
16733
  }, [vue.createElementVNode("div", {
16624
16734
  "class": vue.normalizeClass(['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value]),
16625
- "style": {
16626
- ...textColorStyles.value
16627
- }
16735
+ "style": vue.normalizeStyle(textColorStyles.value)
16628
16736
  }, null), vue.withDirectives(vue.createElementVNode("div", {
16629
16737
  "class": vue.normalizeClass(['v-slider-thumb__ripple', textColorClasses.value]),
16630
16738
  "style": vue.normalizeStyle(textColorStyles.value)
@@ -16637,10 +16745,13 @@
16637
16745
  default: () => [vue.withDirectives(vue.createElementVNode("div", {
16638
16746
  "class": "v-slider-thumb__label-container"
16639
16747
  }, [vue.createElementVNode("div", {
16640
- "class": vue.normalizeClass(['v-slider-thumb__label', textColorClasses.value])
16748
+ "class": vue.normalizeClass(['v-slider-thumb__label', backgroundColorClasses.value]),
16749
+ "style": vue.normalizeStyle(backgroundColorStyles.value)
16641
16750
  }, [vue.createElementVNode("div", null, [slots['thumb-label']?.({
16642
16751
  modelValue: props.modelValue
16643
- }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[vue.vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
16752
+ }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)]), vue.createElementVNode("div", {
16753
+ "class": "v-slider-thumb__label-wedge"
16754
+ }, null)])]), [[vue.vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
16644
16755
  })]);
16645
16756
  });
16646
16757
  return {};
@@ -18787,19 +18898,23 @@
18787
18898
  get: () => {
18788
18899
  return _search.value;
18789
18900
  },
18790
- set: val => {
18901
+ set: async val => {
18791
18902
  _search.value = val ?? '';
18792
18903
  if (!props.multiple && !hasSelectionSlot.value) {
18793
18904
  model.value = [transformItem$3(props, val)];
18794
18905
  vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18795
18906
  }
18796
18907
  if (val && props.multiple && props.delimiters?.length) {
18797
- const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
18908
+ const signsToMatch = props.delimiters.map(escapeForRegex).join('|');
18909
+ const values = val.split(new RegExp(`(?:${signsToMatch})+`));
18798
18910
  if (values.length > 1) {
18799
- values.forEach(v => {
18911
+ for (let v of values) {
18800
18912
  v = v.trim();
18801
- if (v) select(transformItem$3(props, v));
18802
- });
18913
+ if (v) {
18914
+ select(transformItem$3(props, v));
18915
+ await vue.nextTick();
18916
+ }
18917
+ }
18803
18918
  _search.value = '';
18804
18919
  }
18805
18920
  }
@@ -19081,6 +19196,7 @@
19081
19196
  "selected": selectedValues.value,
19082
19197
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
19083
19198
  "onMousedown": e => e.preventDefault(),
19199
+ "selectable": true,
19084
19200
  "onKeydown": onListKeydown,
19085
19201
  "onFocusin": onFocusin,
19086
19202
  "onFocusout": onFocusout,
@@ -22654,6 +22770,9 @@
22654
22770
  let {
22655
22771
  emit
22656
22772
  } = _ref;
22773
+ const {
22774
+ t
22775
+ } = useLocale();
22657
22776
  const disableMonth = vue.computed(() => {
22658
22777
  return Array.isArray(props.disabled) ? props.disabled.includes('text') : !!props.disabled;
22659
22778
  });
@@ -22700,6 +22819,7 @@
22700
22819
  "density": "comfortable",
22701
22820
  "icon": props.modeIcon,
22702
22821
  "variant": "text",
22822
+ "aria-label": t('$vuetify.datePicker.ariaLabel.selectYear'),
22703
22823
  "onClick": onClickYear
22704
22824
  }, null), vue.createVNode(VSpacer, null, null), vue.createElementVNode("div", {
22705
22825
  "class": "v-date-picker-controls__month"
@@ -22709,6 +22829,7 @@
22709
22829
  "density": "comfortable",
22710
22830
  "icon": props.prevIcon,
22711
22831
  "variant": "text",
22832
+ "aria-label": t('$vuetify.datePicker.ariaLabel.previousMonth'),
22712
22833
  "onClick": onClickPrev
22713
22834
  }, null), vue.createVNode(VBtn, {
22714
22835
  "data-testid": "next-month",
@@ -22716,6 +22837,7 @@
22716
22837
  "icon": props.nextIcon,
22717
22838
  "density": "comfortable",
22718
22839
  "variant": "text",
22840
+ "aria-label": t('$vuetify.datePicker.ariaLabel.nextMonth'),
22719
22841
  "onClick": onClickNext
22720
22842
  }, null)])]);
22721
22843
  });
@@ -22980,6 +23102,9 @@
22980
23102
  slots
22981
23103
  } = _ref;
22982
23104
  const daysRef = vue.ref();
23105
+ const {
23106
+ t
23107
+ } = useLocale();
22983
23108
  const {
22984
23109
  daysInMonth,
22985
23110
  model,
@@ -23036,6 +23161,11 @@
23036
23161
  model.value = [rangeStart.value];
23037
23162
  }
23038
23163
  }
23164
+ function getDateAriaLabel(item) {
23165
+ const fullDate = adapter.format(item.date, 'fullDateWithWeekday');
23166
+ const localeKey = item.isToday ? 'currentDate' : 'selectDate';
23167
+ return t(`$vuetify.datePicker.ariaLabel.${localeKey}`, fullDate);
23168
+ }
23039
23169
  function onMultipleClick(value) {
23040
23170
  const index = model.value.findIndex(selection => adapter.isSameDay(selection, value));
23041
23171
  if (index === -1) {
@@ -23087,6 +23217,8 @@
23087
23217
  ripple: false,
23088
23218
  text: item.localized,
23089
23219
  variant: item.isSelected ? 'flat' : item.isToday ? 'outlined' : 'text',
23220
+ 'aria-label': getDateAriaLabel(item),
23221
+ 'aria-current': item.isToday ? 'date' : undefined,
23090
23222
  onClick: () => onClick(item.date)
23091
23223
  },
23092
23224
  item,
@@ -23141,11 +23273,13 @@
23141
23273
  }
23142
23274
  return createRange(12).map(i => {
23143
23275
  const text = adapter.format(date, 'monthShort');
23276
+ const label = adapter.format(date, 'month');
23144
23277
  const isDisabled = !!(!isMonthAllowed(i) || props.min && adapter.isAfter(adapter.startOfMonth(adapter.date(props.min)), date) || props.max && adapter.isAfter(date, adapter.startOfMonth(adapter.date(props.max))));
23145
23278
  date = adapter.getNextMonth(date);
23146
23279
  return {
23147
23280
  isDisabled,
23148
23281
  text,
23282
+ label,
23149
23283
  value: i
23150
23284
  };
23151
23285
  });
@@ -23172,6 +23306,7 @@
23172
23306
  }, [months.value.map((month, i) => {
23173
23307
  const btnProps = {
23174
23308
  active: model.value === i,
23309
+ ariaLabel: month.label,
23175
23310
  color: model.value === i ? props.color : undefined,
23176
23311
  disabled: month.isDisabled,
23177
23312
  rounded: true,
@@ -24178,6 +24313,42 @@
24178
24313
  return item.isDirectory ? `${path}/${item.name}` : path;
24179
24314
  }
24180
24315
 
24316
+ // Utilities
24317
+ // Composables
24318
+ const makeFileFilterProps = propsFactory({
24319
+ filterByType: String
24320
+ }, 'file-accept');
24321
+ function useFileFilter(props) {
24322
+ const fileFilter = vue.computed(() => props.filterByType ? createFilter(props.filterByType) : null);
24323
+ function filterAccepted(files) {
24324
+ if (fileFilter.value) {
24325
+ const accepted = files.filter(fileFilter.value);
24326
+ return {
24327
+ accepted,
24328
+ rejected: files.filter(f => !accepted.includes(f))
24329
+ };
24330
+ }
24331
+ return {
24332
+ accepted: files,
24333
+ rejected: []
24334
+ };
24335
+ }
24336
+ return {
24337
+ filterAccepted
24338
+ };
24339
+ }
24340
+ function createFilter(v) {
24341
+ const types = v.split(',').map(x => x.trim().toLowerCase());
24342
+ const extensionsToMatch = types.filter(x => x.startsWith('.'));
24343
+ const wildcards = types.filter(x => x.endsWith('/*'));
24344
+ const typesToMatch = types.filter(x => !extensionsToMatch.includes(x) && !wildcards.includes(x));
24345
+ return file => {
24346
+ const extension = file.name.split('.').at(-1)?.toLowerCase() ?? '';
24347
+ const typeGroup = file.type.split('/').at(0)?.toLowerCase() ?? '';
24348
+ return typesToMatch.includes(file.type) || extensionsToMatch.includes(`.${extension}`) || wildcards.includes(`${typeGroup}/*`);
24349
+ };
24350
+ }
24351
+
24181
24352
  // Types
24182
24353
 
24183
24354
  const makeVFileInputProps = propsFactory({
@@ -24210,6 +24381,7 @@
24210
24381
  return wrapInArray(val).every(v => v != null && typeof v === 'object');
24211
24382
  }
24212
24383
  },
24384
+ ...makeFileFilterProps(),
24213
24385
  ...makeVFieldProps({
24214
24386
  clearable: true
24215
24387
  })
@@ -24222,7 +24394,8 @@
24222
24394
  'click:control': e => true,
24223
24395
  'mousedown:control': e => true,
24224
24396
  'update:focused': focused => true,
24225
- 'update:modelValue': files => true
24397
+ 'update:modelValue': files => true,
24398
+ rejected: files => true
24226
24399
  },
24227
24400
  setup(props, _ref) {
24228
24401
  let {
@@ -24233,6 +24406,9 @@
24233
24406
  const {
24234
24407
  t
24235
24408
  } = useLocale();
24409
+ const {
24410
+ filterAccepted
24411
+ } = useFileFilter(props);
24236
24412
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
24237
24413
  const {
24238
24414
  isFocused,
@@ -24306,14 +24482,38 @@
24306
24482
  e.stopImmediatePropagation();
24307
24483
  isDragging.value = false;
24308
24484
  if (!inputRef.value || !hasFilesOrFolders(e)) return;
24485
+ const allDroppedFiles = await handleDrop(e);
24486
+ selectAccepted(allDroppedFiles);
24487
+ }
24488
+ function onFileSelection(e) {
24489
+ if (!e.target || e.repack) return; // prevent loop
24490
+
24491
+ if (!props.filterByType) {
24492
+ const target = e.target;
24493
+ model.value = [...(target.files ?? [])];
24494
+ } else {
24495
+ selectAccepted([...e.target.files]);
24496
+ }
24497
+ }
24498
+ function selectAccepted(files) {
24309
24499
  const dataTransfer = new DataTransfer();
24310
- for (const file of await handleDrop(e)) {
24500
+ const {
24501
+ accepted,
24502
+ rejected
24503
+ } = filterAccepted(files);
24504
+ if (rejected.length) {
24505
+ emit('rejected', rejected);
24506
+ }
24507
+ for (const file of accepted) {
24311
24508
  dataTransfer.items.add(file);
24312
24509
  }
24313
24510
  inputRef.value.files = dataTransfer.files;
24314
- inputRef.value.dispatchEvent(new Event('change', {
24511
+ model.value = [...dataTransfer.files];
24512
+ const event = new Event('change', {
24315
24513
  bubbles: true
24316
- }));
24514
+ });
24515
+ event.repack = true;
24516
+ inputRef.value.dispatchEvent(event);
24317
24517
  }
24318
24518
  vue.watch(model, newValue => {
24319
24519
  const hasModelReset = !Array.isArray(newValue) || !newValue.length;
@@ -24330,6 +24530,8 @@
24330
24530
  ...inputProps
24331
24531
  } = VInput.filterProps(props);
24332
24532
  const fieldProps = VField.filterProps(props);
24533
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
24534
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
24333
24535
  return vue.createVNode(VInput, vue.mergeProps({
24334
24536
  "ref": vInputRef,
24335
24537
  "modelValue": props.multiple ? model.value : model.value[0],
@@ -24385,6 +24587,7 @@
24385
24587
  return vue.createElementVNode(vue.Fragment, null, [vue.createElementVNode("input", vue.mergeProps({
24386
24588
  "ref": inputRef,
24387
24589
  "type": "file",
24590
+ "accept": inputAccept,
24388
24591
  "readonly": isReadonly.value,
24389
24592
  "disabled": isDisabled.value,
24390
24593
  "multiple": props.multiple,
@@ -24394,11 +24597,7 @@
24394
24597
  if (isReadonly.value) e.preventDefault();
24395
24598
  onFocus();
24396
24599
  },
24397
- "onChange": e => {
24398
- if (!e.target) return;
24399
- const target = e.target;
24400
- model.value = [...(target.files ?? [])];
24401
- },
24600
+ "onChange": onFileSelection,
24402
24601
  "onDragleave": onDragleave,
24403
24602
  "onFocus": onFocus,
24404
24603
  "onBlur": blur
@@ -31918,6 +32117,7 @@
31918
32117
  },
31919
32118
  showSize: Boolean,
31920
32119
  name: String,
32120
+ ...makeFileFilterProps(),
31921
32121
  ...makeDelayProps(),
31922
32122
  ...makeDensityProps(),
31923
32123
  ...pick(makeVDividerProps({
@@ -31930,11 +32130,13 @@
31930
32130
  inheritAttrs: false,
31931
32131
  props: makeVFileUploadProps(),
31932
32132
  emits: {
31933
- 'update:modelValue': files => true
32133
+ 'update:modelValue': files => true,
32134
+ rejected: files => true
31934
32135
  },
31935
32136
  setup(props, _ref) {
31936
32137
  let {
31937
32138
  attrs,
32139
+ emit,
31938
32140
  slots
31939
32141
  } = _ref;
31940
32142
  const {
@@ -31943,6 +32145,9 @@
31943
32145
  const {
31944
32146
  densityClasses
31945
32147
  } = useDensity(props);
32148
+ const {
32149
+ filterAccepted
32150
+ } = useFileFilter(props);
31946
32151
  const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
31947
32152
  const isDragging = vue.shallowRef(false);
31948
32153
  const vSheetRef = vue.ref(null);
@@ -31964,14 +32169,38 @@
31964
32169
  e.stopImmediatePropagation();
31965
32170
  isDragging.value = false;
31966
32171
  if (!inputRef.value) return;
32172
+ const allDroppedFiles = await handleDrop(e);
32173
+ selectAccepted(allDroppedFiles);
32174
+ }
32175
+ function onFileSelection(e) {
32176
+ if (!e.target || e.repack) return; // prevent loop
32177
+
32178
+ if (!props.filterByType) {
32179
+ const target = e.target;
32180
+ model.value = [...(target.files ?? [])];
32181
+ } else {
32182
+ selectAccepted([...e.target.files]);
32183
+ }
32184
+ }
32185
+ function selectAccepted(files) {
31967
32186
  const dataTransfer = new DataTransfer();
31968
- for (const file of await handleDrop(e)) {
32187
+ const {
32188
+ accepted,
32189
+ rejected
32190
+ } = filterAccepted(files);
32191
+ if (rejected.length) {
32192
+ emit('rejected', rejected);
32193
+ }
32194
+ for (const file of accepted) {
31969
32195
  dataTransfer.items.add(file);
31970
32196
  }
31971
32197
  inputRef.value.files = dataTransfer.files;
31972
- inputRef.value.dispatchEvent(new Event('change', {
32198
+ model.value = [...dataTransfer.files];
32199
+ const event = new Event('change', {
31973
32200
  bubbles: true
31974
- }));
32201
+ });
32202
+ event.repack = true;
32203
+ inputRef.value.dispatchEvent(event);
31975
32204
  }
31976
32205
  function onClick() {
31977
32206
  inputRef.value?.click();
@@ -31989,17 +32218,16 @@
31989
32218
  const cardProps = VSheet.filterProps(props);
31990
32219
  const dividerProps = VDivider.filterProps(props);
31991
32220
  const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
32221
+ const expectsDirectory = attrs.webkitdirectory !== undefined && attrs.webkitdirectory !== false;
32222
+ const inputAccept = expectsDirectory ? undefined : props.filterByType ?? String(attrs.accept);
31992
32223
  const inputNode = vue.createElementVNode("input", vue.mergeProps({
31993
32224
  "ref": inputRef,
31994
32225
  "type": "file",
32226
+ "accept": inputAccept,
31995
32227
  "disabled": props.disabled,
31996
32228
  "multiple": props.multiple,
31997
32229
  "name": props.name,
31998
- "onChange": e => {
31999
- if (!e.target) return;
32000
- const target = e.target;
32001
- model.value = [...(target.files ?? [])];
32002
- }
32230
+ "onChange": onFileSelection
32003
32231
  }, inputAttrs), null);
32004
32232
  return vue.createElementVNode(vue.Fragment, null, [vue.createVNode(VSheet, vue.mergeProps({
32005
32233
  "ref": vSheetRef
@@ -35104,7 +35332,7 @@
35104
35332
  };
35105
35333
  });
35106
35334
  }
35107
- const version$1 = "3.9.2-master.2025-07-28";
35335
+ const version$1 = "3.9.3-dev.2025-07-30";
35108
35336
  createVuetify$1.version = version$1;
35109
35337
 
35110
35338
  // Vue's inject() can only be used in setup
@@ -35402,7 +35630,7 @@
35402
35630
 
35403
35631
  /* eslint-disable local-rules/sort-imports */
35404
35632
 
35405
- const version = "3.9.2-master.2025-07-28";
35633
+ const version = "3.9.3-dev.2025-07-30";
35406
35634
 
35407
35635
  /* eslint-disable local-rules/sort-imports */
35408
35636