@vuetify/nightly 3.8.7-master.2025-06-02 → 3.8.8-dev.2025-06-04

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 (180) hide show
  1. package/CHANGELOG.md +33 -11
  2. package/dist/json/attributes.json +2042 -1942
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +146 -146
  5. package/dist/json/tags.json +25 -0
  6. package/dist/json/web-types.json +3842 -3510
  7. package/dist/vuetify-labs.cjs +380 -152
  8. package/dist/vuetify-labs.css +5726 -5686
  9. package/dist/vuetify-labs.d.ts +2393 -1889
  10. package/dist/vuetify-labs.esm.js +381 -153
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +380 -152
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +374 -141
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +2674 -2634
  17. package/dist/vuetify.d.ts +1548 -1084
  18. package/dist/vuetify.esm.js +375 -142
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +374 -141
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1226 -1208
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VAlert/VAlert.css +6 -1
  26. package/lib/components/VAlert/VAlert.d.ts +35 -0
  27. package/lib/components/VAlert/VAlert.js +15 -10
  28. package/lib/components/VAlert/VAlert.js.map +1 -1
  29. package/lib/components/VAlert/VAlert.sass +7 -1
  30. package/lib/components/VAppBar/VAppBar.d.ts +15 -3
  31. package/lib/components/VAppBar/VAppBarNavIcon.d.ts +20 -10
  32. package/lib/components/VAutocomplete/VAutocomplete.css +6 -6
  33. package/lib/components/VAutocomplete/VAutocomplete.d.ts +154 -103
  34. package/lib/components/VAutocomplete/VAutocomplete.js +21 -3
  35. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  36. package/lib/components/VAutocomplete/VAutocomplete.sass +3 -9
  37. package/lib/components/VBtn/VBtn.d.ts +20 -10
  38. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  39. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  40. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  41. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  42. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  43. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  44. package/lib/components/VCard/VCard.d.ts +20 -10
  45. package/lib/components/VCheckbox/VCheckbox.d.ts +23 -13
  46. package/lib/components/VCheckbox/VCheckboxBtn.d.ts +20 -10
  47. package/lib/components/VChip/VChip.d.ts +20 -10
  48. package/lib/components/VChip/VChip.js +1 -0
  49. package/lib/components/VChip/VChip.js.map +1 -1
  50. package/lib/components/VChipGroup/VChipGroup.d.ts +10 -0
  51. package/lib/components/VCombobox/VCombobox.css +6 -6
  52. package/lib/components/VCombobox/VCombobox.d.ts +154 -103
  53. package/lib/components/VCombobox/VCombobox.js +22 -3
  54. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  55. package/lib/components/VCombobox/VCombobox.sass +3 -9
  56. package/lib/components/VDataTable/VDataTable.d.ts +60 -0
  57. package/lib/components/VDataTable/VDataTableHeaders.d.ts +13 -0
  58. package/lib/components/VDataTable/VDataTableHeaders.js +4 -2
  59. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  60. package/lib/components/VDataTable/VDataTableServer.d.ts +42 -0
  61. package/lib/components/VDataTable/VDataTableVirtual.d.ts +42 -0
  62. package/lib/components/VDatePicker/VDatePicker.d.ts +10 -0
  63. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +10 -0
  64. package/lib/components/VDatePicker/VDatePickerMonth.js +1 -1
  65. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  66. package/lib/components/VExpansionPanel/VExpansionPanel.d.ts +20 -10
  67. package/lib/components/VExpansionPanel/VExpansionPanelTitle.d.ts +20 -10
  68. package/lib/components/VExpansionPanel/VExpansionPanels.d.ts +20 -10
  69. package/lib/components/VFab/VFab.d.ts +20 -10
  70. package/lib/components/VField/VField.d.ts +3 -3
  71. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  72. package/lib/components/VInput/VInput.d.ts +4 -4
  73. package/lib/components/VList/VList.d.ts +13 -0
  74. package/lib/components/VList/VList.js +4 -1
  75. package/lib/components/VList/VList.js.map +1 -1
  76. package/lib/components/VList/VListChildren.js.map +1 -1
  77. package/lib/components/VList/VListItem.d.ts +23 -10
  78. package/lib/components/VList/VListItem.js +7 -3
  79. package/lib/components/VList/VListItem.js.map +1 -1
  80. package/lib/components/VList/list.d.ts +9 -2
  81. package/lib/components/VList/list.js +7 -0
  82. package/lib/components/VList/list.js.map +1 -1
  83. package/lib/components/VNumberInput/VNumberInput.d.ts +103 -89
  84. package/lib/components/VNumberInput/VNumberInput.js +19 -4
  85. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  86. package/lib/components/VOtpInput/VOtpInput.js +2 -1
  87. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  88. package/lib/components/VOverlay/VOverlay.css +1 -1
  89. package/lib/components/VOverlay/_variables.scss +1 -1
  90. package/lib/components/VRadio/VRadio.d.ts +20 -10
  91. package/lib/components/VRadioGroup/VRadioGroup.d.ts +23 -13
  92. package/lib/components/VRangeSlider/VRangeSlider.d.ts +3 -3
  93. package/lib/components/VSelect/VSelect.css +6 -0
  94. package/lib/components/VSelect/VSelect.d.ts +171 -107
  95. package/lib/components/VSelect/VSelect.js +21 -3
  96. package/lib/components/VSelect/VSelect.js.map +1 -1
  97. package/lib/components/VSelect/VSelect.sass +3 -0
  98. package/lib/components/VSelect/_mixins.scss +14 -0
  99. package/lib/components/VSelectionControl/VSelectionControl.d.ts +20 -10
  100. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.d.ts +28 -14
  101. package/lib/components/VSlideGroup/VSlideGroup.d.ts +10 -0
  102. package/lib/components/VSlideGroup/VSlideGroup.js +2 -1
  103. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  104. package/lib/components/VSlider/VSlider.d.ts +3 -3
  105. package/lib/components/VSlider/VSliderThumb.d.ts +20 -10
  106. package/lib/components/VSlider/VSliderThumb.js +12 -6
  107. package/lib/components/VSlider/VSliderThumb.js.map +1 -1
  108. package/lib/components/VSlider/slider.js +4 -1
  109. package/lib/components/VSlider/slider.js.map +1 -1
  110. package/lib/components/VStepper/VStepperItem.d.ts +28 -14
  111. package/lib/components/VSwitch/VSwitch.d.ts +23 -13
  112. package/lib/components/VTable/VTable.css +6 -0
  113. package/lib/components/VTable/VTable.d.ts +55 -24
  114. package/lib/components/VTable/VTable.js +9 -2
  115. package/lib/components/VTable/VTable.js.map +1 -1
  116. package/lib/components/VTable/VTable.sass +14 -0
  117. package/lib/components/VTable/_variables.scss +1 -0
  118. package/lib/components/VTabs/VTab.d.ts +56 -28
  119. package/lib/components/VTabs/VTabs.d.ts +10 -0
  120. package/lib/components/VTextField/VTextField.d.ts +27 -27
  121. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  122. package/lib/components/VToolbar/VToolbar.d.ts +15 -3
  123. package/lib/components/VToolbar/VToolbar.js +6 -3
  124. package/lib/components/VToolbar/VToolbar.js.map +1 -1
  125. package/lib/composables/calendar.d.ts +6 -0
  126. package/lib/composables/calendar.js +2 -1
  127. package/lib/composables/calendar.js.map +1 -1
  128. package/lib/composables/date/DateAdapter.d.ts +3 -3
  129. package/lib/composables/date/DateAdapter.js.map +1 -1
  130. package/lib/composables/date/adapters/string.d.ts +54 -0
  131. package/lib/composables/date/adapters/string.js +153 -0
  132. package/lib/composables/date/adapters/string.js.map +1 -0
  133. package/lib/composables/date/adapters/vuetify.d.ts +1 -1
  134. package/lib/composables/date/adapters/vuetify.js +4 -4
  135. package/lib/composables/date/adapters/vuetify.js.map +1 -1
  136. package/lib/composables/date/date.d.ts +3 -3
  137. package/lib/composables/date/index.d.ts +1 -0
  138. package/lib/composables/date/index.js +1 -0
  139. package/lib/composables/date/index.js.map +1 -1
  140. package/lib/composables/filter.js +3 -0
  141. package/lib/composables/filter.js.map +1 -1
  142. package/lib/composables/iconSizes.d.ts +28 -0
  143. package/lib/composables/iconSizes.js +23 -0
  144. package/lib/composables/iconSizes.js.map +1 -0
  145. package/lib/composables/list-items.js +2 -2
  146. package/lib/composables/list-items.js.map +1 -1
  147. package/lib/composables/theme.d.ts +6 -1
  148. package/lib/composables/theme.js +94 -26
  149. package/lib/composables/theme.js.map +1 -1
  150. package/lib/composables/virtual.js +6 -1
  151. package/lib/composables/virtual.js.map +1 -1
  152. package/lib/directives/ripple/index.d.ts +2 -1
  153. package/lib/directives/ripple/index.js +12 -7
  154. package/lib/directives/ripple/index.js.map +1 -1
  155. package/lib/entry-bundler.d.ts +3 -3
  156. package/lib/entry-bundler.js +1 -1
  157. package/lib/entry-bundler.js.map +1 -1
  158. package/lib/framework.d.ts +73 -58
  159. package/lib/framework.js +1 -1
  160. package/lib/framework.js.map +1 -1
  161. package/lib/labs/VCalendar/VCalendar.d.ts +10 -0
  162. package/lib/labs/VColorInput/VColorInput.d.ts +3 -3
  163. package/lib/labs/VDateInput/VDateInput.d.ts +97 -87
  164. package/lib/labs/VFileUpload/VFileUpload.d.ts +3 -3
  165. package/lib/labs/VFileUpload/VFileUploadItem.d.ts +20 -10
  166. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  167. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  168. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  169. package/lib/labs/VStepperVertical/VStepperVertical.d.ts +20 -10
  170. package/lib/labs/VStepperVertical/VStepperVerticalItem.d.ts +20 -10
  171. package/lib/labs/VTreeview/VTreeview.d.ts +13 -0
  172. package/lib/labs/VTreeview/VTreeviewItem.d.ts +20 -10
  173. package/lib/labs/entry-bundler.d.ts +3 -3
  174. package/lib/util/globals.d.ts +1 -0
  175. package/lib/util/globals.js +1 -0
  176. package/lib/util/globals.js.map +1 -1
  177. package/lib/util/helpers.d.ts +1 -0
  178. package/lib/util/helpers.js +9 -1
  179. package/lib/util/helpers.js.map +1 -1
  180. package/package.json +3 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.7-master.2025-06-02
2
+ * Vuetify v3.8.8-dev.2025-06-04
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -85,6 +85,7 @@
85
85
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
86
86
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
87
87
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
88
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
88
89
 
89
90
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
90
91
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -606,6 +607,14 @@
606
607
  }
607
608
  return cleanText;
608
609
  }
610
+ function camelizeProps(props) {
611
+ if (!props) return;
612
+ const out = {};
613
+ for (const prop in props) {
614
+ out[vue.camelize(prop)] = props[prop];
615
+ }
616
+ return out;
617
+ }
609
618
 
610
619
  // Utilities
611
620
  const block = ['top', 'bottom'];
@@ -2341,6 +2350,7 @@
2341
2350
  function genDefaults$2() {
2342
2351
  return {
2343
2352
  defaultTheme: 'light',
2353
+ prefix: 'v-',
2344
2354
  variations: {
2345
2355
  colors: [],
2346
2356
  lighten: 0,
@@ -2422,7 +2432,10 @@
2422
2432
  }
2423
2433
  }
2424
2434
  },
2425
- stylesheetId: 'vuetify-theme-stylesheet'
2435
+ stylesheetId: 'vuetify-theme-stylesheet',
2436
+ scoped: false,
2437
+ unimportant: false,
2438
+ utilities: true
2426
2439
  };
2427
2440
  }
2428
2441
  function parseThemeOptions() {
@@ -2445,21 +2458,21 @@
2445
2458
  function createCssClass(lines, selector, content, scope) {
2446
2459
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2447
2460
  }
2448
- function genCssVariables(theme) {
2461
+ function genCssVariables(theme, prefix) {
2449
2462
  const lightOverlay = theme.dark ? 2 : 1;
2450
2463
  const darkOverlay = theme.dark ? 1 : 2;
2451
2464
  const variables = [];
2452
2465
  for (const [key, value] of Object.entries(theme.colors)) {
2453
2466
  const rgb = parseColor(value);
2454
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2467
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2455
2468
  if (!key.startsWith('on-')) {
2456
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2469
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2457
2470
  }
2458
2471
  }
2459
2472
  for (const [key, value] of Object.entries(theme.variables)) {
2460
2473
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2461
2474
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2462
- variables.push(`--v-${key}: ${rgb ?? value}`);
2475
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2463
2476
  }
2464
2477
  return variables;
2465
2478
  }
@@ -2503,7 +2516,8 @@
2503
2516
  const scopeSelector = `:where(${scope})`;
2504
2517
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2505
2518
  }
2506
- function upsertStyles(styleEl, styles) {
2519
+ function upsertStyles(id, cspNonce, styles) {
2520
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2507
2521
  if (!styleEl) return;
2508
2522
  styleEl.innerHTML = styles;
2509
2523
  }
@@ -2523,8 +2537,17 @@
2523
2537
  // Composables
2524
2538
  function createTheme(options) {
2525
2539
  const parsedOptions = parseThemeOptions(options);
2526
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2540
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2527
2541
  const themes = vue.ref(parsedOptions.themes);
2542
+ const systemName = vue.shallowRef('light');
2543
+ const name = vue.computed({
2544
+ get() {
2545
+ return _name.value === 'system' ? systemName.value : _name.value;
2546
+ },
2547
+ set(val) {
2548
+ _name.value = val;
2549
+ }
2550
+ });
2528
2551
  const computedThemes = vue.computed(() => {
2529
2552
  const acc = {};
2530
2553
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2545,28 +2568,49 @@
2545
2568
  const current = vue.toRef(() => computedThemes.value[name.value]);
2546
2569
  const styles = vue.computed(() => {
2547
2570
  const lines = [];
2571
+ const important = parsedOptions.unimportant ? '' : ' !important';
2572
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2548
2573
  if (current.value?.dark) {
2549
2574
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2550
2575
  }
2551
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2576
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2552
2577
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2553
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2554
- }
2555
- const bgLines = [];
2556
- const fgLines = [];
2557
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2558
- for (const key of colors) {
2559
- if (key.startsWith('on-')) {
2560
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2561
- } else {
2562
- createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`], parsedOptions.scope);
2563
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2564
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2578
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2579
+ }
2580
+ if (parsedOptions.utilities) {
2581
+ const bgLines = [];
2582
+ const fgLines = [];
2583
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2584
+ for (const key of colors) {
2585
+ if (key.startsWith('on-')) {
2586
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2587
+ } else {
2588
+ createCssClass(bgLines, `.${scoped}bg-${key}`, [`--${parsedOptions.prefix}theme-overlay-multiplier: var(--${parsedOptions.prefix}theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`, `color: rgb(var(--${parsedOptions.prefix}theme-on-${key}))${important}`], parsedOptions.scope);
2589
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2590
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2591
+ }
2565
2592
  }
2593
+ lines.push(...bgLines, ...fgLines);
2566
2594
  }
2567
- lines.push(...bgLines, ...fgLines);
2568
2595
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2569
2596
  });
2597
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2598
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2599
+ if (SUPPORTS_MATCH_MEDIA) {
2600
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2601
+ function updateSystemName() {
2602
+ systemName.value = media.matches ? 'dark' : 'light';
2603
+ }
2604
+ updateSystemName();
2605
+ media.addEventListener('change', updateSystemName, {
2606
+ passive: true
2607
+ });
2608
+ if (vue.getCurrentScope()) {
2609
+ vue.onScopeDispose(() => {
2610
+ media.removeEventListener('change', updateSystemName);
2611
+ });
2612
+ }
2613
+ }
2570
2614
  function install(app) {
2571
2615
  if (parsedOptions.isDisabled) return;
2572
2616
  const head = app._context.provides.usehead;
@@ -2604,22 +2648,55 @@
2604
2648
  updateStyles();
2605
2649
  }
2606
2650
  function updateStyles() {
2607
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2651
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2608
2652
  }
2609
2653
  }
2610
2654
  }
2611
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2655
+ function change(themeName) {
2656
+ if (!themeNames.value.includes(themeName)) {
2657
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2658
+ return;
2659
+ }
2660
+ name.value = themeName;
2661
+ }
2662
+ function cycle() {
2663
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2664
+ const currentIndex = themeArray.indexOf(name.value);
2665
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2666
+ change(themeArray[nextIndex]);
2667
+ }
2668
+ function toggle() {
2669
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2670
+ cycle(themeArray);
2671
+ }
2672
+ const globalName = new Proxy(name, {
2673
+ get(target, prop) {
2674
+ return target[prop];
2675
+ },
2676
+ set(target, prop, val) {
2677
+ if (prop === 'value') {
2678
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2679
+ }
2680
+ // @ts-expect-error
2681
+ target[prop] = val;
2682
+ return true;
2683
+ }
2684
+ });
2612
2685
  return {
2613
2686
  install,
2687
+ change,
2688
+ cycle,
2689
+ toggle,
2614
2690
  isDisabled: parsedOptions.isDisabled,
2615
2691
  name,
2616
2692
  themes,
2617
2693
  current,
2618
2694
  computedThemes,
2695
+ prefix: parsedOptions.prefix,
2619
2696
  themeClasses,
2620
2697
  styles,
2621
2698
  global: {
2622
- name,
2699
+ name: globalName,
2623
2700
  current
2624
2701
  }
2625
2702
  };
@@ -2630,7 +2707,7 @@
2630
2707
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2631
2708
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2632
2709
  const current = vue.toRef(() => theme.themes.value[name.value]);
2633
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2710
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2634
2711
  const newTheme = {
2635
2712
  ...theme,
2636
2713
  name,
@@ -3734,7 +3811,10 @@
3734
3811
  default: 'default',
3735
3812
  validator: v => allowedDensities$1.includes(v)
3736
3813
  },
3737
- extended: Boolean,
3814
+ extended: {
3815
+ type: Boolean,
3816
+ default: null
3817
+ },
3738
3818
  extensionHeight: {
3739
3819
  type: [Number, String],
3740
3820
  default: 48
@@ -3782,7 +3862,7 @@
3782
3862
  const {
3783
3863
  rtlClasses
3784
3864
  } = useRtl();
3785
- const isExtended = vue.shallowRef(!!(props.extended || slots.extension?.()));
3865
+ const isExtended = vue.shallowRef(props.extended === null ? !!slots.extension?.() : props.extended);
3786
3866
  const contentHeight = vue.computed(() => parseInt(Number(props.height) + (props.density === 'prominent' ? Number(props.height) : 0) - (props.density === 'comfortable' ? 8 : 0) - (props.density === 'compact' ? 16 : 0), 10));
3787
3867
  const extensionHeight = vue.computed(() => isExtended.value ? parseInt(Number(props.extensionHeight) + (props.density === 'prominent' ? Number(props.extensionHeight) : 0) - (props.density === 'comfortable' ? 4 : 0) - (props.density === 'compact' ? 8 : 0), 10) : 0);
3788
3868
  provideDefaults({
@@ -3794,7 +3874,7 @@
3794
3874
  const hasTitle = !!(props.title || slots.title);
3795
3875
  const hasImage = !!(slots.image || props.image);
3796
3876
  const extension = slots.extension?.();
3797
- isExtended.value = !!(props.extended || extension);
3877
+ isExtended.value = props.extended === null ? !!extension : props.extended;
3798
3878
  return vue.createVNode(props.tag, {
3799
3879
  "class": vue.normalizeClass(['v-toolbar', {
3800
3880
  'v-toolbar--absolute': props.absolute,
@@ -4177,9 +4257,15 @@
4177
4257
  };
4178
4258
  }
4179
4259
 
4260
+ // Types
4261
+
4180
4262
  const makeVBtnGroupProps = propsFactory({
4181
4263
  baseColor: String,
4182
4264
  divided: Boolean,
4265
+ direction: {
4266
+ type: String,
4267
+ default: 'horizontal'
4268
+ },
4183
4269
  ...makeBorderProps(),
4184
4270
  ...makeComponentProps(),
4185
4271
  ...makeDensityProps(),
@@ -4213,7 +4299,7 @@
4213
4299
  } = useRounded(props);
4214
4300
  provideDefaults({
4215
4301
  VBtn: {
4216
- height: 'auto',
4302
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4217
4303
  baseColor: vue.toRef(() => props.baseColor),
4218
4304
  color: vue.toRef(() => props.color),
4219
4305
  density: vue.toRef(() => props.density),
@@ -4223,7 +4309,7 @@
4223
4309
  });
4224
4310
  useRender(() => {
4225
4311
  return vue.createVNode(props.tag, {
4226
- "class": vue.normalizeClass(['v-btn-group', {
4312
+ "class": vue.normalizeClass(['v-btn-group', `v-btn-group--${props.direction}`, {
4227
4313
  'v-btn-group--divided': props.divided
4228
4314
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
4229
4315
  "style": vue.normalizeStyle(props.style)
@@ -5555,8 +5641,8 @@
5555
5641
  window.clearTimeout(element._ripple.showTimer);
5556
5642
  }
5557
5643
  let keyboardRipple = false;
5558
- function keyboardRippleShow(e) {
5559
- if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
5644
+ function keyboardRippleShow(e, keys) {
5645
+ if (!keyboardRipple && keys.includes(e.keyCode)) {
5560
5646
  keyboardRipple = true;
5561
5647
  rippleShow(e);
5562
5648
  }
@@ -5584,9 +5670,12 @@
5584
5670
  el._ripple.enabled = enabled;
5585
5671
  el._ripple.centered = modifiers.center;
5586
5672
  el._ripple.circle = modifiers.circle;
5587
- if (isObject(value) && value.class) {
5588
- el._ripple.class = value.class;
5673
+ const bindingValue = isObject(value) ? value : {};
5674
+ if (bindingValue.class) {
5675
+ el._ripple.class = bindingValue.class;
5589
5676
  }
5677
+ const allowedKeys = bindingValue.keys ?? [keyCodes.enter, keyCodes.space];
5678
+ el._ripple.keyDownHandler = e => keyboardRippleShow(e, allowedKeys);
5590
5679
  if (enabled && !wasEnabled) {
5591
5680
  if (modifiers.stop) {
5592
5681
  el.addEventListener('touchstart', rippleStop, {
@@ -5608,7 +5697,7 @@
5608
5697
  el.addEventListener('mousedown', rippleShow);
5609
5698
  el.addEventListener('mouseup', rippleHide);
5610
5699
  el.addEventListener('mouseleave', rippleHide);
5611
- el.addEventListener('keydown', keyboardRippleShow);
5700
+ el.addEventListener('keydown', e => keyboardRippleShow(e, allowedKeys));
5612
5701
  el.addEventListener('keyup', keyboardRippleHide);
5613
5702
  el.addEventListener('blur', focusRippleHide);
5614
5703
 
@@ -5628,7 +5717,9 @@
5628
5717
  el.removeEventListener('touchcancel', rippleHide);
5629
5718
  el.removeEventListener('mouseup', rippleHide);
5630
5719
  el.removeEventListener('mouseleave', rippleHide);
5631
- el.removeEventListener('keydown', keyboardRippleShow);
5720
+ if (el._ripple?.keyDownHandler) {
5721
+ el.removeEventListener('keydown', el._ripple.keyDownHandler);
5722
+ }
5632
5723
  el.removeEventListener('keyup', keyboardRippleHide);
5633
5724
  el.removeEventListener('dragstart', rippleHide);
5634
5725
  el.removeEventListener('blur', focusRippleHide);
@@ -5637,8 +5728,8 @@
5637
5728
  updateRipple(el, binding, false);
5638
5729
  }
5639
5730
  function unmounted$4(el) {
5640
- delete el._ripple;
5641
5731
  removeListeners(el);
5732
+ delete el._ripple;
5642
5733
  }
5643
5734
  function updated$1(el, binding) {
5644
5735
  if (binding.value === binding.oldValue) {
@@ -5911,6 +6002,31 @@
5911
6002
  // Utilities
5912
6003
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5913
6004
 
6005
+ // Utilities
6006
+
6007
+ // Types
6008
+
6009
+ // Types
6010
+
6011
+ // Composables
6012
+ const makeIconSizeProps = propsFactory({
6013
+ iconSize: [Number, String],
6014
+ iconSizes: {
6015
+ type: Array,
6016
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6017
+ }
6018
+ }, 'iconSize');
6019
+ function useIconSizes(props, fallback) {
6020
+ const iconSize = vue.computed(() => {
6021
+ const iconSizeMap = new Map(props.iconSizes);
6022
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6023
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6024
+ });
6025
+ return {
6026
+ iconSize
6027
+ };
6028
+ }
6029
+
5914
6030
  // Types
5915
6031
 
5916
6032
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5950,6 +6066,7 @@
5950
6066
  ...makeDensityProps(),
5951
6067
  ...makeDimensionProps(),
5952
6068
  ...makeElevationProps(),
6069
+ ...makeIconSizeProps(),
5953
6070
  ...makeLocationProps(),
5954
6071
  ...makePositionProps(),
5955
6072
  ...makeRoundedProps(),
@@ -5977,6 +6094,9 @@
5977
6094
  if (!props.type) return props.icon;
5978
6095
  return props.icon ?? `$${props.type}`;
5979
6096
  });
6097
+ const {
6098
+ iconSize
6099
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5980
6100
  const {
5981
6101
  themeClasses
5982
6102
  } = provideTheme(props);
@@ -6024,6 +6144,11 @@
6024
6144
  const hasPrepend = !!(slots.prepend || icon.value);
6025
6145
  const hasTitle = !!(slots.title || props.title);
6026
6146
  const hasClose = !!(slots.close || props.closable);
6147
+ const iconProps = {
6148
+ density: props.density,
6149
+ icon: icon.value,
6150
+ size: iconSize.value
6151
+ };
6027
6152
  return isActive.value && vue.createVNode(props.tag, {
6028
6153
  "class": vue.normalizeClass(['v-alert', props.border && {
6029
6154
  'v-alert--border': !!props.border,
@@ -6041,19 +6166,14 @@
6041
6166
  }, null), hasPrepend && vue.createElementVNode("div", {
6042
6167
  "key": "prepend",
6043
6168
  "class": "v-alert__prepend"
6044
- }, [!slots.prepend ? vue.createVNode(VIcon, {
6045
- "key": "prepend-icon",
6046
- "density": props.density,
6047
- "icon": icon.value,
6048
- "size": props.prominent ? 44 : 28
6049
- }, null) : vue.createVNode(VDefaultsProvider, {
6169
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6170
+ "key": "prepend-icon"
6171
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6050
6172
  "key": "prepend-defaults",
6051
6173
  "disabled": !icon.value,
6052
6174
  "defaults": {
6053
6175
  VIcon: {
6054
- density: props.density,
6055
- icon: icon.value,
6056
- size: props.prominent ? 44 : 28
6176
+ ...iconProps
6057
6177
  }
6058
6178
  }
6059
6179
  }, slots.prepend)]), vue.createElementVNode("div", {
@@ -7578,6 +7698,7 @@
7578
7698
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7579
7699
  const makeVSlideGroupProps = propsFactory({
7580
7700
  centerActive: Boolean,
7701
+ contentClass: null,
7581
7702
  direction: {
7582
7703
  type: String,
7583
7704
  default: 'horizontal'
@@ -7890,7 +8011,7 @@
7890
8011
  })]), vue.createElementVNode("div", {
7891
8012
  "key": "container",
7892
8013
  "ref": containerRef,
7893
- "class": "v-slide-group__container",
8014
+ "class": vue.normalizeClass(['v-slide-group__container', props.contentClass]),
7894
8015
  "onScroll": onScroll
7895
8016
  }, [vue.createElementVNode("div", {
7896
8017
  "ref": contentRef,
@@ -8100,6 +8221,7 @@
8100
8221
  const isClickable = vue.computed(() => !props.disabled && props.link !== false && (!!group || props.link || link.isClickable.value));
8101
8222
  const closeProps = vue.toRef(() => ({
8102
8223
  'aria-label': t(props.closeLabel),
8224
+ disabled: props.disabled,
8103
8225
  onClick(e) {
8104
8226
  e.preventDefault();
8105
8227
  e.stopPropagation();
@@ -8252,16 +8374,85 @@
8252
8374
  }
8253
8375
  });
8254
8376
 
8377
+ const makeVDividerProps = propsFactory({
8378
+ color: String,
8379
+ inset: Boolean,
8380
+ length: [Number, String],
8381
+ opacity: [Number, String],
8382
+ thickness: [Number, String],
8383
+ vertical: Boolean,
8384
+ ...makeComponentProps(),
8385
+ ...makeThemeProps()
8386
+ }, 'VDivider');
8387
+ const VDivider = genericComponent()({
8388
+ name: 'VDivider',
8389
+ props: makeVDividerProps(),
8390
+ setup(props, _ref) {
8391
+ let {
8392
+ attrs,
8393
+ slots
8394
+ } = _ref;
8395
+ const {
8396
+ themeClasses
8397
+ } = provideTheme(props);
8398
+ const {
8399
+ textColorClasses,
8400
+ textColorStyles
8401
+ } = useTextColor(() => props.color);
8402
+ const dividerStyles = vue.computed(() => {
8403
+ const styles = {};
8404
+ if (props.length) {
8405
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8406
+ }
8407
+ if (props.thickness) {
8408
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8409
+ }
8410
+ return styles;
8411
+ });
8412
+ useRender(() => {
8413
+ const divider = vue.createElementVNode("hr", {
8414
+ "class": vue.normalizeClass([{
8415
+ 'v-divider': true,
8416
+ 'v-divider--inset': props.inset,
8417
+ 'v-divider--vertical': props.vertical
8418
+ }, themeClasses.value, textColorClasses.value, props.class]),
8419
+ "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
8420
+ '--v-border-opacity': props.opacity
8421
+ }, props.style]),
8422
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8423
+ "role": `${attrs.role || 'separator'}`
8424
+ }, null);
8425
+ if (!slots.default) return divider;
8426
+ return vue.createElementVNode("div", {
8427
+ "class": vue.normalizeClass(['v-divider__wrapper', {
8428
+ 'v-divider__wrapper--vertical': props.vertical,
8429
+ 'v-divider__wrapper--inset': props.inset
8430
+ }])
8431
+ }, [divider, vue.createElementVNode("div", {
8432
+ "class": "v-divider__content"
8433
+ }, [slots.default()]), divider]);
8434
+ });
8435
+ return {};
8436
+ }
8437
+ });
8438
+
8255
8439
  // Utilities
8256
8440
 
8257
8441
  // List
8258
8442
  const ListKey = Symbol.for('vuetify:list');
8259
8443
  function createList() {
8444
+ let {
8445
+ filterable
8446
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
8447
+ filterable: false
8448
+ };
8260
8449
  const parent = vue.inject(ListKey, {
8450
+ filterable: false,
8261
8451
  hasPrepend: vue.shallowRef(false),
8262
8452
  updateHasPrepend: () => null
8263
8453
  });
8264
8454
  const data = {
8455
+ filterable: parent.filterable || filterable,
8265
8456
  hasPrepend: vue.shallowRef(false),
8266
8457
  updateHasPrepend: value => {
8267
8458
  if (value) data.hasPrepend.value = value;
@@ -9213,6 +9404,9 @@
9213
9404
  roundedClasses
9214
9405
  } = useRounded(roundedProps);
9215
9406
  const lineClasses = vue.toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
9407
+ const rippleOptions = vue.toRef(() => props.ripple !== undefined && !!props.ripple && list?.filterable ? {
9408
+ keys: [keyCodes.enter]
9409
+ } : props.ripple);
9216
9410
  const slotProps = vue.computed(() => ({
9217
9411
  isActive: isActive.value,
9218
9412
  select,
@@ -9237,8 +9431,9 @@
9237
9431
  function onKeyDown(e) {
9238
9432
  const target = e.target;
9239
9433
  if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
9240
- if (e.key === 'Enter' || e.key === ' ') {
9434
+ if (e.key === 'Enter' || e.key === ' ' && !list?.filterable) {
9241
9435
  e.preventDefault();
9436
+ e.stopPropagation();
9242
9437
  e.target.dispatchEvent(new MouseEvent('click', e));
9243
9438
  }
9244
9439
  }
@@ -9348,7 +9543,7 @@
9348
9543
  }), vue.createElementVNode("div", {
9349
9544
  "class": "v-list-item__spacer"
9350
9545
  }, null)])]
9351
- }), [[Ripple, isClickable.value && props.ripple]]);
9546
+ }), [[Ripple, isClickable.value && rippleOptions.value]]);
9352
9547
  });
9353
9548
  return {
9354
9549
  activate,
@@ -9403,68 +9598,6 @@
9403
9598
  }
9404
9599
  });
9405
9600
 
9406
- const makeVDividerProps = propsFactory({
9407
- color: String,
9408
- inset: Boolean,
9409
- length: [Number, String],
9410
- opacity: [Number, String],
9411
- thickness: [Number, String],
9412
- vertical: Boolean,
9413
- ...makeComponentProps(),
9414
- ...makeThemeProps()
9415
- }, 'VDivider');
9416
- const VDivider = genericComponent()({
9417
- name: 'VDivider',
9418
- props: makeVDividerProps(),
9419
- setup(props, _ref) {
9420
- let {
9421
- attrs,
9422
- slots
9423
- } = _ref;
9424
- const {
9425
- themeClasses
9426
- } = provideTheme(props);
9427
- const {
9428
- textColorClasses,
9429
- textColorStyles
9430
- } = useTextColor(() => props.color);
9431
- const dividerStyles = vue.computed(() => {
9432
- const styles = {};
9433
- if (props.length) {
9434
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9435
- }
9436
- if (props.thickness) {
9437
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9438
- }
9439
- return styles;
9440
- });
9441
- useRender(() => {
9442
- const divider = vue.createElementVNode("hr", {
9443
- "class": vue.normalizeClass([{
9444
- 'v-divider': true,
9445
- 'v-divider--inset': props.inset,
9446
- 'v-divider--vertical': props.vertical
9447
- }, themeClasses.value, textColorClasses.value, props.class]),
9448
- "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
9449
- '--v-border-opacity': props.opacity
9450
- }, props.style]),
9451
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9452
- "role": `${attrs.role || 'separator'}`
9453
- }, null);
9454
- if (!slots.default) return divider;
9455
- return vue.createElementVNode("div", {
9456
- "class": vue.normalizeClass(['v-divider__wrapper', {
9457
- 'v-divider__wrapper--vertical': props.vertical,
9458
- 'v-divider__wrapper--inset': props.inset
9459
- }])
9460
- }, [divider, vue.createElementVNode("div", {
9461
- "class": "v-divider__content"
9462
- }, [slots.default()]), divider]);
9463
- });
9464
- return {};
9465
- }
9466
- });
9467
-
9468
9601
  // Types
9469
9602
 
9470
9603
  const makeVListChildrenProps = propsFactory({
@@ -9581,7 +9714,7 @@
9581
9714
  const _props = {
9582
9715
  title,
9583
9716
  value,
9584
- ...itemProps
9717
+ ...camelizeProps(itemProps)
9585
9718
  };
9586
9719
  return {
9587
9720
  title: String(_props.title ?? ''),
@@ -9733,6 +9866,7 @@
9733
9866
  activeClass: String,
9734
9867
  bgColor: String,
9735
9868
  disabled: Boolean,
9869
+ filterable: Boolean,
9736
9870
  expandIcon: IconValue,
9737
9871
  collapseIcon: IconValue,
9738
9872
  lines: {
@@ -9816,7 +9950,9 @@
9816
9950
  const activeColor = vue.toRef(() => props.activeColor);
9817
9951
  const baseColor = vue.toRef(() => props.baseColor);
9818
9952
  const color = vue.toRef(() => props.color);
9819
- createList();
9953
+ createList({
9954
+ filterable: props.filterable
9955
+ });
9820
9956
  provideDefaults({
9821
9957
  VListGroup: {
9822
9958
  activeColor,
@@ -12392,7 +12528,12 @@
12392
12528
  }
12393
12529
  function calculateOffset(index) {
12394
12530
  index = clamp(index, 0, items.value.length - 1);
12395
- return offsets[index] || 0;
12531
+ const whole = Math.floor(index);
12532
+ const fraction = index % 1;
12533
+ const next = whole + 1;
12534
+ const wholeOffset = offsets[whole] || 0;
12535
+ const nextOffset = offsets[next] || wholeOffset;
12536
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12396
12537
  }
12397
12538
  function calculateIndex(scrollTop) {
12398
12539
  return binaryClosest(offsets, scrollTop);
@@ -12746,6 +12887,7 @@
12746
12887
  },
12747
12888
  openOnClear: Boolean,
12748
12889
  itemColor: String,
12890
+ noAutoScroll: Boolean,
12749
12891
  ...makeItemsProps({
12750
12892
  itemChildren: false
12751
12893
  })
@@ -12960,7 +13102,7 @@
12960
13102
  vue.watch(menu, () => {
12961
13103
  if (!props.hideSelected && menu.value && model.value.length) {
12962
13104
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
12963
- IN_BROWSER && window.requestAnimationFrame(() => {
13105
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
12964
13106
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
12965
13107
  });
12966
13108
  }
@@ -13052,6 +13194,22 @@
13052
13194
  key: item.value,
13053
13195
  onClick: () => select(item, null)
13054
13196
  });
13197
+ if (item.raw.type === 'divider') {
13198
+ return slots.divider?.({
13199
+ props: item.raw,
13200
+ index
13201
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13202
+ "key": `divider-${index}`
13203
+ }), null);
13204
+ }
13205
+ if (item.raw.type === 'subheader') {
13206
+ return slots.subheader?.({
13207
+ props: item.raw,
13208
+ index
13209
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13210
+ "key": `subheader-${index}`
13211
+ }), null);
13212
+ }
13055
13213
  return slots.item?.({
13056
13214
  item,
13057
13215
  index,
@@ -13212,6 +13370,9 @@
13212
13370
  let match = -1;
13213
13371
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13214
13372
  if (typeof item === 'object') {
13373
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13374
+ continue;
13375
+ }
13215
13376
  const filterKeys = keys || Object.keys(transformed);
13216
13377
  for (const key of filterKeys) {
13217
13378
  const value = getPropertyFromItem(transformed, key);
@@ -13414,7 +13575,7 @@
13414
13575
  menu.value = !menu.value;
13415
13576
  }
13416
13577
  function onListKeydown(e) {
13417
- if (e.key !== ' ' && checkPrintable(e)) {
13578
+ if (checkPrintable(e) || e.key === 'Backspace') {
13418
13579
  vTextFieldRef.value?.focus();
13419
13580
  }
13420
13581
  }
@@ -13619,6 +13780,7 @@
13619
13780
  }, props.menuProps), {
13620
13781
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
13621
13782
  "ref": listRef,
13783
+ "filterable": true,
13622
13784
  "selected": selectedValues.value,
13623
13785
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
13624
13786
  "onMousedown": e => e.preventDefault(),
@@ -13650,6 +13812,22 @@
13650
13812
  active: highlightFirst.value && index === 0 ? true : undefined,
13651
13813
  onClick: () => select(item, null)
13652
13814
  });
13815
+ if (item.raw.type === 'divider') {
13816
+ return slots.divider?.({
13817
+ props: item.raw,
13818
+ index
13819
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13820
+ "key": `divider-${index}`
13821
+ }), null);
13822
+ }
13823
+ if (item.raw.type === 'subheader') {
13824
+ return slots.subheader?.({
13825
+ props: item.raw,
13826
+ index
13827
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13828
+ "key": `subheader-${index}`
13829
+ }), null);
13830
+ }
13653
13831
  return slots.item?.({
13654
13832
  item,
13655
13833
  index,
@@ -15888,7 +16066,10 @@
15888
16066
  if (step.value <= 0) return value;
15889
16067
  const clamped = clamp(value, min.value, max.value);
15890
16068
  const offset = min.value % step.value;
15891
- const newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
16069
+ let newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
16070
+ if (clamped > newValue && newValue + step.value > max.value) {
16071
+ newValue = max.value;
16072
+ }
15892
16073
  return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value));
15893
16074
  }
15894
16075
  return {
@@ -16144,6 +16325,8 @@
16144
16325
  } = useRtl();
16145
16326
  if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider');
16146
16327
  const {
16328
+ min,
16329
+ max,
16147
16330
  thumbColor,
16148
16331
  step,
16149
16332
  disabled,
@@ -16184,16 +16367,20 @@
16184
16367
  if (!relevantKeys.includes(e.key)) return;
16185
16368
  e.preventDefault();
16186
16369
  const _step = step.value || 0.1;
16187
- const steps = (props.max - props.min) / _step;
16370
+ const steps = (max.value - min.value) / _step;
16188
16371
  if ([left, right, down, up].includes(e.key)) {
16189
16372
  const increase = vertical.value ? [isRtl.value ? left : right, isReversed.value ? down : up] : indexFromEnd.value !== isRtl.value ? [left, up] : [right, up];
16190
16373
  const direction = increase.includes(e.key) ? 1 : -1;
16191
16374
  const multiplier = e.shiftKey ? 2 : e.ctrlKey ? 1 : 0;
16192
- value = value + direction * _step * multipliers.value[multiplier];
16375
+ if (direction === -1 && value === max.value && !multiplier && !Number.isInteger(steps)) {
16376
+ value = value - steps % 1 * _step;
16377
+ } else {
16378
+ value = value + direction * _step * multipliers.value[multiplier];
16379
+ }
16193
16380
  } else if (e.key === home) {
16194
- value = props.min;
16381
+ value = min.value;
16195
16382
  } else if (e.key === end) {
16196
- value = props.max;
16383
+ value = max.value;
16197
16384
  } else {
16198
16385
  const direction = e.key === pagedown ? 1 : -1;
16199
16386
  value = value - direction * _step * (steps > 100 ? steps / 10 : 10);
@@ -16218,8 +16405,8 @@
16218
16405
  "role": "slider",
16219
16406
  "tabindex": disabled.value ? -1 : 0,
16220
16407
  "aria-label": props.name,
16221
- "aria-valuemin": props.min,
16222
- "aria-valuemax": props.max,
16408
+ "aria-valuemin": min.value,
16409
+ "aria-valuemax": max.value,
16223
16410
  "aria-valuenow": props.modelValue,
16224
16411
  "aria-readonly": !!readonly.value,
16225
16412
  "aria-orientation": direction.value,
@@ -17245,13 +17432,13 @@
17245
17432
  return null;
17246
17433
  }
17247
17434
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17248
- function getWeekdays(locale, firstDayOfWeek) {
17435
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17249
17436
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17250
17437
  return createRange(7).map(i => {
17251
17438
  const weekday = new Date(sundayJanuarySecond2000);
17252
17439
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17253
17440
  return new Intl.DateTimeFormat(locale, {
17254
- weekday: 'narrow'
17441
+ weekday: weekdayFormat ?? 'narrow'
17255
17442
  }).format(weekday);
17256
17443
  });
17257
17444
  }
@@ -17715,9 +17902,9 @@
17715
17902
  getDiff(date, comparing, unit) {
17716
17903
  return getDiff(date, comparing, unit);
17717
17904
  }
17718
- getWeekdays(firstDayOfWeek) {
17905
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17719
17906
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17720
- return getWeekdays(this.locale, firstDay);
17907
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17721
17908
  }
17722
17909
  getYear(date) {
17723
17910
  return getYear(date);
@@ -18073,6 +18260,7 @@
18073
18260
  _search.value = val ?? '';
18074
18261
  if (!props.multiple && !hasSelectionSlot.value) {
18075
18262
  model.value = [transformItem$3(props, val)];
18263
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18076
18264
  }
18077
18265
  if (val && props.multiple && props.delimiters?.length) {
18078
18266
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18153,7 +18341,7 @@
18153
18341
  menu.value = !menu.value;
18154
18342
  }
18155
18343
  function onListKeydown(e) {
18156
- if (e.key !== ' ' && checkPrintable(e)) {
18344
+ if (checkPrintable(e) || e.key === 'Backspace') {
18157
18345
  vTextFieldRef.value?.focus();
18158
18346
  }
18159
18347
  }
@@ -18358,6 +18546,7 @@
18358
18546
  }, props.menuProps), {
18359
18547
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18360
18548
  "ref": listRef,
18549
+ "filterable": true,
18361
18550
  "selected": selectedValues.value,
18362
18551
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18363
18552
  "onMousedown": e => e.preventDefault(),
@@ -18389,6 +18578,22 @@
18389
18578
  active: highlightFirst.value && index === 0 ? true : undefined,
18390
18579
  onClick: () => select(item, null)
18391
18580
  });
18581
+ if (item.raw.type === 'divider') {
18582
+ return slots.divider?.({
18583
+ props: item.raw,
18584
+ index
18585
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18586
+ "key": `divider-${index}`
18587
+ }), null);
18588
+ }
18589
+ if (item.raw.type === 'subheader') {
18590
+ return slots.subheader?.({
18591
+ props: item.raw,
18592
+ index
18593
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18594
+ "key": `subheader-${index}`
18595
+ }), null);
18596
+ }
18392
18597
  return slots.item?.({
18393
18598
  item,
18394
18599
  index,
@@ -20268,6 +20473,7 @@
20268
20473
  color: String,
20269
20474
  disableSort: Boolean,
20270
20475
  fixedHeader: Boolean,
20476
+ lastFixed: Boolean,
20271
20477
  multiSort: Boolean,
20272
20478
  sortAscIcon: {
20273
20479
  type: IconValue,
@@ -20314,10 +20520,11 @@
20314
20520
  loaderClasses
20315
20521
  } = useLoader(props);
20316
20522
  function getFixedStyles(column, y) {
20317
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20523
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20318
20524
  return {
20319
20525
  position: 'sticky',
20320
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20526
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20527
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20321
20528
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20322
20529
  };
20323
20530
  }
@@ -20826,11 +21033,18 @@
20826
21033
  }
20827
21034
  });
20828
21035
 
21036
+ // Types
21037
+
20829
21038
  const makeVTableProps = propsFactory({
20830
21039
  fixedHeader: Boolean,
20831
21040
  fixedFooter: Boolean,
20832
21041
  height: [Number, String],
20833
21042
  hover: Boolean,
21043
+ striped: {
21044
+ type: String,
21045
+ default: null,
21046
+ validator: v => ['even', 'odd'].includes(v)
21047
+ },
20834
21048
  ...makeComponentProps(),
20835
21049
  ...makeDensityProps(),
20836
21050
  ...makeTagProps(),
@@ -20857,7 +21071,9 @@
20857
21071
  'v-table--fixed-footer': props.fixedFooter,
20858
21072
  'v-table--has-top': !!slots.top,
20859
21073
  'v-table--has-bottom': !!slots.bottom,
20860
- 'v-table--hover': props.hover
21074
+ 'v-table--hover': props.hover,
21075
+ 'v-table--striped-even': props.striped === 'even',
21076
+ 'v-table--striped-odd': props.striped === 'odd'
20861
21077
  }, themeClasses.value, densityClasses.value, props.class]),
20862
21078
  "style": vue.normalizeStyle(props.style)
20863
21079
  }, {
@@ -22032,7 +22248,8 @@
22032
22248
  firstDayOfWeek: {
22033
22249
  type: [Number, String],
22034
22250
  default: undefined
22035
- }
22251
+ },
22252
+ weekdayFormat: String
22036
22253
  }, 'calendar');
22037
22254
  function useCalendar(props) {
22038
22255
  const adapter = useDate();
@@ -22273,7 +22490,7 @@
22273
22490
  "ref": daysRef,
22274
22491
  "key": daysInMonth.value[0].date?.toString(),
22275
22492
  "class": "v-date-picker-month__days"
22276
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => vue.createElementVNode("div", {
22493
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => vue.createElementVNode("div", {
22277
22494
  "class": vue.normalizeClass(['v-date-picker-month__day', 'v-date-picker-month__weekday'])
22278
22495
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22279
22496
  const slotProps = {
@@ -24863,6 +25080,10 @@
24863
25080
  type: Number,
24864
25081
  default: 0
24865
25082
  },
25083
+ minFractionDigits: {
25084
+ type: Number,
25085
+ default: null
25086
+ },
24866
25087
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24867
25088
  }, 'VNumberInput');
24868
25089
  const VNumberInput = genericComponent()({
@@ -24893,9 +25114,19 @@
24893
25114
  } = useFocus(props);
24894
25115
  function correctPrecision(val) {
24895
25116
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
24896
- const fixed = precision == null ? String(val) : val.toFixed(precision);
24897
- return isFocused.value ? Number(fixed).toString() // trim zeros
24898
- : fixed;
25117
+ if (precision == null) {
25118
+ return String(val);
25119
+ }
25120
+ let fixed = val.toFixed(precision);
25121
+ if (isFocused.value) {
25122
+ return Number(fixed).toString(); // trim zeros
25123
+ }
25124
+ if ((props.minFractionDigits ?? precision) < precision) {
25125
+ const trimLimit = precision - props.minFractionDigits;
25126
+ const [baseDigits, fractionDigits] = fixed.split('.');
25127
+ fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
25128
+ }
25129
+ return fixed;
24899
25130
  }
24900
25131
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24901
25132
  const _inputText = vue.shallowRef(null);
@@ -24950,6 +25181,7 @@
24950
25181
  }
24951
25182
  };
24952
25183
  vue.watch(() => props.precision, () => formatInputValue());
25184
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
24953
25185
  vue.onMounted(() => {
24954
25186
  clampModel();
24955
25187
  });
@@ -25064,7 +25296,7 @@
25064
25296
  inputText.value = null;
25065
25297
  return;
25066
25298
  }
25067
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25299
+ inputText.value = correctPrecision(model.value);
25068
25300
  }
25069
25301
  function trimDecimalZeros() {
25070
25302
  if (controlsDisabled.value) return;
@@ -25324,9 +25556,10 @@
25324
25556
  e.preventDefault();
25325
25557
  e.stopPropagation();
25326
25558
  const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
25559
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25327
25560
  if (isValidNumber(clipboardText)) return;
25328
25561
  model.value = clipboardText.split('');
25329
- inputRef.value?.[index].blur();
25562
+ inputRef.value?.[finalIndex].focus();
25330
25563
  }
25331
25564
  function reset() {
25332
25565
  model.value = [];
@@ -30029,11 +30262,6 @@
30029
30262
  hideOverlay: Boolean,
30030
30263
  icon: [String, Function, Object],
30031
30264
  iconColor: String,
30032
- iconSize: [Number, String],
30033
- iconSizes: {
30034
- type: Array,
30035
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
30036
- },
30037
30265
  loading: Boolean,
30038
30266
  opacity: [Number, String],
30039
30267
  readonly: Boolean,
@@ -30053,6 +30281,7 @@
30053
30281
  ...makeBorderProps(),
30054
30282
  ...makeComponentProps(),
30055
30283
  ...makeElevationProps(),
30284
+ ...makeIconSizeProps(),
30056
30285
  ...makeRoundedProps(),
30057
30286
  ...makeTagProps({
30058
30287
  tag: 'button'
@@ -30107,7 +30336,6 @@
30107
30336
  })()
30108
30337
  }));
30109
30338
  const btnSizeMap = new Map(props.sizes);
30110
- const iconSizeMap = new Map(props.iconSizes);
30111
30339
  function onClick() {
30112
30340
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
30113
30341
  isActive.value = !isActive.value;
@@ -30119,12 +30347,12 @@
30119
30347
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
30120
30348
  const btnHeight = props.height ?? btnSize;
30121
30349
  const btnWidth = props.width ?? btnSize;
30122
- const _iconSize = props.iconSize;
30123
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
30124
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30350
+ const {
30351
+ iconSize
30352
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
30125
30353
  const iconProps = {
30126
30354
  icon,
30127
- size: iconSize,
30355
+ size: iconSize.value,
30128
30356
  iconColor: props.iconColor,
30129
30357
  opacity: props.opacity
30130
30358
  };
@@ -30167,7 +30395,7 @@
30167
30395
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30168
30396
  "indeterminate": "disable-shrink",
30169
30397
  "width": "2",
30170
- "size": iconSize
30398
+ "size": iconSize.value
30171
30399
  }, null)])]
30172
30400
  });
30173
30401
  });
@@ -32077,7 +32305,7 @@
32077
32305
  };
32078
32306
  });
32079
32307
  }
32080
- const version$1 = "3.8.7-master.2025-06-02";
32308
+ const version$1 = "3.8.8-dev.2025-06-04";
32081
32309
  createVuetify$1.version = version$1;
32082
32310
 
32083
32311
  // Vue's inject() can only be used in setup
@@ -32375,7 +32603,7 @@
32375
32603
 
32376
32604
  /* eslint-disable local-rules/sort-imports */
32377
32605
 
32378
- const version = "3.8.7-master.2025-06-02";
32606
+ const version = "3.8.8-dev.2025-06-04";
32379
32607
 
32380
32608
  /* eslint-disable local-rules/sort-imports */
32381
32609