@vuetify/nightly 3.8.8-master.2025-06-10 → 3.8.9-dev.2025-06-12

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 +44 -19
  2. package/dist/json/attributes.json +2771 -2411
  3. package/dist/json/importMap-labs.json +32 -28
  4. package/dist/json/importMap.json +128 -128
  5. package/dist/json/tags.json +96 -1
  6. package/dist/json/web-types.json +5703 -4391
  7. package/dist/vuetify-labs.cjs +635 -146
  8. package/dist/vuetify-labs.css +4248 -4214
  9. package/dist/vuetify-labs.d.ts +9097 -1977
  10. package/dist/vuetify-labs.esm.js +636 -147
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +635 -146
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +383 -135
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +5999 -5965
  17. package/dist/vuetify.d.ts +1586 -1085
  18. package/dist/vuetify.esm.js +384 -136
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +383 -135
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1219 -1203
  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.d.ts +154 -103
  33. package/lib/components/VAutocomplete/VAutocomplete.js +21 -3
  34. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  35. package/lib/components/VBadge/VBadge.d.ts +60 -0
  36. package/lib/components/VBadge/VBadge.js +7 -2
  37. package/lib/components/VBadge/VBadge.js.map +1 -1
  38. package/lib/components/VBtn/VBtn.d.ts +20 -10
  39. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  40. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  41. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  42. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  43. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  44. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  45. package/lib/components/VCard/VCard.d.ts +20 -10
  46. package/lib/components/VCheckbox/VCheckbox.d.ts +23 -13
  47. package/lib/components/VCheckbox/VCheckboxBtn.d.ts +20 -10
  48. package/lib/components/VChip/VChip.d.ts +20 -10
  49. package/lib/components/VChipGroup/VChipGroup.d.ts +10 -0
  50. package/lib/components/VCombobox/VCombobox.d.ts +154 -103
  51. package/lib/components/VCombobox/VCombobox.js +22 -3
  52. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  53. package/lib/components/VDataTable/VDataTable.d.ts +60 -0
  54. package/lib/components/VDataTable/VDataTableHeaders.d.ts +13 -0
  55. package/lib/components/VDataTable/VDataTableHeaders.js +4 -2
  56. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  57. package/lib/components/VDataTable/VDataTableServer.d.ts +42 -0
  58. package/lib/components/VDataTable/VDataTableVirtual.d.ts +42 -0
  59. package/lib/components/VDatePicker/VDatePicker.d.ts +10 -0
  60. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +10 -0
  61. package/lib/components/VDatePicker/VDatePickerMonth.js +1 -1
  62. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  63. package/lib/components/VExpansionPanel/VExpansionPanel.d.ts +20 -10
  64. package/lib/components/VExpansionPanel/VExpansionPanelTitle.d.ts +20 -10
  65. package/lib/components/VExpansionPanel/VExpansionPanels.d.ts +20 -10
  66. package/lib/components/VFab/VFab.d.ts +20 -10
  67. package/lib/components/VField/VField.d.ts +3 -3
  68. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  69. package/lib/components/VInfiniteScroll/VInfiniteScroll.d.ts +9 -3
  70. package/lib/components/VInfiniteScroll/VInfiniteScroll.js +29 -0
  71. package/lib/components/VInfiniteScroll/VInfiniteScroll.js.map +1 -1
  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.d.ts +171 -107
  94. package/lib/components/VSelect/VSelect.js +21 -3
  95. package/lib/components/VSelect/VSelect.js.map +1 -1
  96. package/lib/components/VSelectionControl/VSelectionControl.d.ts +20 -10
  97. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.d.ts +28 -14
  98. package/lib/components/VSlideGroup/VSlideGroup.d.ts +10 -0
  99. package/lib/components/VSlideGroup/VSlideGroup.js +2 -1
  100. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  101. package/lib/components/VSlider/VSlider.d.ts +3 -3
  102. package/lib/components/VSlider/VSliderThumb.d.ts +20 -10
  103. package/lib/components/VStepper/VStepperItem.d.ts +28 -14
  104. package/lib/components/VSwitch/VSwitch.d.ts +23 -13
  105. package/lib/components/VTable/VTable.css +6 -0
  106. package/lib/components/VTable/VTable.d.ts +55 -24
  107. package/lib/components/VTable/VTable.js +9 -2
  108. package/lib/components/VTable/VTable.js.map +1 -1
  109. package/lib/components/VTable/VTable.sass +14 -0
  110. package/lib/components/VTable/_variables.scss +1 -0
  111. package/lib/components/VTabs/VTab.d.ts +56 -28
  112. package/lib/components/VTabs/VTabs.d.ts +10 -0
  113. package/lib/components/VTextField/VTextField.d.ts +27 -27
  114. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  115. package/lib/components/VToolbar/VToolbar.d.ts +15 -3
  116. package/lib/components/VToolbar/VToolbar.js +6 -3
  117. package/lib/components/VToolbar/VToolbar.js.map +1 -1
  118. package/lib/composables/calendar.d.ts +6 -0
  119. package/lib/composables/calendar.js +2 -1
  120. package/lib/composables/calendar.js.map +1 -1
  121. package/lib/composables/date/DateAdapter.d.ts +3 -3
  122. package/lib/composables/date/DateAdapter.js.map +1 -1
  123. package/lib/composables/date/adapters/string.d.ts +54 -0
  124. package/lib/composables/date/adapters/string.js +153 -0
  125. package/lib/composables/date/adapters/string.js.map +1 -0
  126. package/lib/composables/date/adapters/vuetify.d.ts +1 -1
  127. package/lib/composables/date/adapters/vuetify.js +4 -4
  128. package/lib/composables/date/adapters/vuetify.js.map +1 -1
  129. package/lib/composables/date/date.d.ts +3 -3
  130. package/lib/composables/date/index.d.ts +1 -0
  131. package/lib/composables/date/index.js +1 -0
  132. package/lib/composables/date/index.js.map +1 -1
  133. package/lib/composables/filter.js +3 -0
  134. package/lib/composables/filter.js.map +1 -1
  135. package/lib/composables/iconSizes.d.ts +28 -0
  136. package/lib/composables/iconSizes.js +23 -0
  137. package/lib/composables/iconSizes.js.map +1 -0
  138. package/lib/composables/mask.d.ts +38 -0
  139. package/lib/composables/mask.js +183 -0
  140. package/lib/composables/mask.js.map +1 -0
  141. package/lib/composables/theme.d.ts +6 -1
  142. package/lib/composables/theme.js +94 -26
  143. package/lib/composables/theme.js.map +1 -1
  144. package/lib/composables/virtual.js +6 -1
  145. package/lib/composables/virtual.js.map +1 -1
  146. package/lib/directives/ripple/index.d.ts +2 -1
  147. package/lib/directives/ripple/index.js +12 -7
  148. package/lib/directives/ripple/index.js.map +1 -1
  149. package/lib/entry-bundler.d.ts +3 -3
  150. package/lib/entry-bundler.js +1 -1
  151. package/lib/entry-bundler.js.map +1 -1
  152. package/lib/framework.d.ts +72 -56
  153. package/lib/framework.js +1 -1
  154. package/lib/framework.js.map +1 -1
  155. package/lib/labs/VCalendar/VCalendar.d.ts +10 -0
  156. package/lib/labs/VColorInput/VColorInput.d.ts +3 -3
  157. package/lib/labs/VDateInput/VDateInput.d.ts +97 -87
  158. package/lib/labs/VFileUpload/VFileUpload.d.ts +3 -3
  159. package/lib/labs/VFileUpload/VFileUploadItem.d.ts +20 -10
  160. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  161. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  162. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  163. package/lib/labs/VMaskInput/VMaskInput.d.ts +6993 -0
  164. package/lib/labs/VMaskInput/VMaskInput.js +67 -0
  165. package/lib/labs/VMaskInput/VMaskInput.js.map +1 -0
  166. package/lib/labs/VMaskInput/index.d.ts +1 -0
  167. package/lib/labs/VMaskInput/index.js +2 -0
  168. package/lib/labs/VMaskInput/index.js.map +1 -0
  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/components.d.ts +1 -0
  174. package/lib/labs/components.js +1 -0
  175. package/lib/labs/components.js.map +1 -1
  176. package/lib/labs/entry-bundler.d.ts +3 -3
  177. package/lib/util/globals.d.ts +1 -0
  178. package/lib/util/globals.js +1 -0
  179. package/lib/util/globals.js.map +1 -1
  180. package/package.json +3 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.8-master.2025-06-10
2
+ * Vuetify v3.8.9-dev.2025-06-12
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"); }
@@ -2348,6 +2349,7 @@
2348
2349
  function genDefaults$2() {
2349
2350
  return {
2350
2351
  defaultTheme: 'light',
2352
+ prefix: 'v-',
2351
2353
  variations: {
2352
2354
  colors: [],
2353
2355
  lighten: 0,
@@ -2429,7 +2431,10 @@
2429
2431
  }
2430
2432
  }
2431
2433
  },
2432
- stylesheetId: 'vuetify-theme-stylesheet'
2434
+ stylesheetId: 'vuetify-theme-stylesheet',
2435
+ scoped: false,
2436
+ unimportant: false,
2437
+ utilities: true
2433
2438
  };
2434
2439
  }
2435
2440
  function parseThemeOptions() {
@@ -2452,21 +2457,21 @@
2452
2457
  function createCssClass(lines, selector, content, scope) {
2453
2458
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2454
2459
  }
2455
- function genCssVariables(theme) {
2460
+ function genCssVariables(theme, prefix) {
2456
2461
  const lightOverlay = theme.dark ? 2 : 1;
2457
2462
  const darkOverlay = theme.dark ? 1 : 2;
2458
2463
  const variables = [];
2459
2464
  for (const [key, value] of Object.entries(theme.colors)) {
2460
2465
  const rgb = parseColor(value);
2461
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2466
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2462
2467
  if (!key.startsWith('on-')) {
2463
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2468
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2464
2469
  }
2465
2470
  }
2466
2471
  for (const [key, value] of Object.entries(theme.variables)) {
2467
2472
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2468
2473
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2469
- variables.push(`--v-${key}: ${rgb ?? value}`);
2474
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2470
2475
  }
2471
2476
  return variables;
2472
2477
  }
@@ -2510,7 +2515,8 @@
2510
2515
  const scopeSelector = `:where(${scope})`;
2511
2516
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2512
2517
  }
2513
- function upsertStyles(styleEl, styles) {
2518
+ function upsertStyles(id, cspNonce, styles) {
2519
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2514
2520
  if (!styleEl) return;
2515
2521
  styleEl.innerHTML = styles;
2516
2522
  }
@@ -2530,8 +2536,17 @@
2530
2536
  // Composables
2531
2537
  function createTheme(options) {
2532
2538
  const parsedOptions = parseThemeOptions(options);
2533
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2539
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2534
2540
  const themes = vue.ref(parsedOptions.themes);
2541
+ const systemName = vue.shallowRef('light');
2542
+ const name = vue.computed({
2543
+ get() {
2544
+ return _name.value === 'system' ? systemName.value : _name.value;
2545
+ },
2546
+ set(val) {
2547
+ _name.value = val;
2548
+ }
2549
+ });
2535
2550
  const computedThemes = vue.computed(() => {
2536
2551
  const acc = {};
2537
2552
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2552,28 +2567,49 @@
2552
2567
  const current = vue.toRef(() => computedThemes.value[name.value]);
2553
2568
  const styles = vue.computed(() => {
2554
2569
  const lines = [];
2570
+ const important = parsedOptions.unimportant ? '' : ' !important';
2571
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2555
2572
  if (current.value?.dark) {
2556
2573
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2557
2574
  }
2558
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2575
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2559
2576
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2560
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2561
- }
2562
- const bgLines = [];
2563
- const fgLines = [];
2564
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2565
- for (const key of colors) {
2566
- if (key.startsWith('on-')) {
2567
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2568
- } else {
2569
- 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);
2570
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2571
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2577
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2578
+ }
2579
+ if (parsedOptions.utilities) {
2580
+ const bgLines = [];
2581
+ const fgLines = [];
2582
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2583
+ for (const key of colors) {
2584
+ if (key.startsWith('on-')) {
2585
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2586
+ } else {
2587
+ 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);
2588
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2589
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2590
+ }
2572
2591
  }
2592
+ lines.push(...bgLines, ...fgLines);
2573
2593
  }
2574
- lines.push(...bgLines, ...fgLines);
2575
2594
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2576
2595
  });
2596
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2597
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2598
+ if (SUPPORTS_MATCH_MEDIA) {
2599
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2600
+ function updateSystemName() {
2601
+ systemName.value = media.matches ? 'dark' : 'light';
2602
+ }
2603
+ updateSystemName();
2604
+ media.addEventListener('change', updateSystemName, {
2605
+ passive: true
2606
+ });
2607
+ if (vue.getCurrentScope()) {
2608
+ vue.onScopeDispose(() => {
2609
+ media.removeEventListener('change', updateSystemName);
2610
+ });
2611
+ }
2612
+ }
2577
2613
  function install(app) {
2578
2614
  if (parsedOptions.isDisabled) return;
2579
2615
  const head = app._context.provides.usehead;
@@ -2611,22 +2647,55 @@
2611
2647
  updateStyles();
2612
2648
  }
2613
2649
  function updateStyles() {
2614
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2650
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2615
2651
  }
2616
2652
  }
2617
2653
  }
2618
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2654
+ function change(themeName) {
2655
+ if (!themeNames.value.includes(themeName)) {
2656
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2657
+ return;
2658
+ }
2659
+ name.value = themeName;
2660
+ }
2661
+ function cycle() {
2662
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2663
+ const currentIndex = themeArray.indexOf(name.value);
2664
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2665
+ change(themeArray[nextIndex]);
2666
+ }
2667
+ function toggle() {
2668
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2669
+ cycle(themeArray);
2670
+ }
2671
+ const globalName = new Proxy(name, {
2672
+ get(target, prop) {
2673
+ return target[prop];
2674
+ },
2675
+ set(target, prop, val) {
2676
+ if (prop === 'value') {
2677
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2678
+ }
2679
+ // @ts-expect-error
2680
+ target[prop] = val;
2681
+ return true;
2682
+ }
2683
+ });
2619
2684
  return {
2620
2685
  install,
2686
+ change,
2687
+ cycle,
2688
+ toggle,
2621
2689
  isDisabled: parsedOptions.isDisabled,
2622
2690
  name,
2623
2691
  themes,
2624
2692
  current,
2625
2693
  computedThemes,
2694
+ prefix: parsedOptions.prefix,
2626
2695
  themeClasses,
2627
2696
  styles,
2628
2697
  global: {
2629
- name,
2698
+ name: globalName,
2630
2699
  current
2631
2700
  }
2632
2701
  };
@@ -2637,7 +2706,7 @@
2637
2706
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2638
2707
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2639
2708
  const current = vue.toRef(() => theme.themes.value[name.value]);
2640
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2709
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2641
2710
  const newTheme = {
2642
2711
  ...theme,
2643
2712
  name,
@@ -3741,7 +3810,10 @@
3741
3810
  default: 'default',
3742
3811
  validator: v => allowedDensities$1.includes(v)
3743
3812
  },
3744
- extended: Boolean,
3813
+ extended: {
3814
+ type: Boolean,
3815
+ default: null
3816
+ },
3745
3817
  extensionHeight: {
3746
3818
  type: [Number, String],
3747
3819
  default: 48
@@ -3789,7 +3861,7 @@
3789
3861
  const {
3790
3862
  rtlClasses
3791
3863
  } = useRtl();
3792
- const isExtended = vue.shallowRef(!!(props.extended || slots.extension?.()));
3864
+ const isExtended = vue.shallowRef(props.extended === null ? !!slots.extension?.() : props.extended);
3793
3865
  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));
3794
3866
  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);
3795
3867
  provideDefaults({
@@ -3801,7 +3873,7 @@
3801
3873
  const hasTitle = !!(props.title || slots.title);
3802
3874
  const hasImage = !!(slots.image || props.image);
3803
3875
  const extension = slots.extension?.();
3804
- isExtended.value = !!(props.extended || extension);
3876
+ isExtended.value = props.extended === null ? !!extension : props.extended;
3805
3877
  return vue.createVNode(props.tag, {
3806
3878
  "class": vue.normalizeClass(['v-toolbar', {
3807
3879
  'v-toolbar--absolute': props.absolute,
@@ -4184,9 +4256,15 @@
4184
4256
  };
4185
4257
  }
4186
4258
 
4259
+ // Types
4260
+
4187
4261
  const makeVBtnGroupProps = propsFactory({
4188
4262
  baseColor: String,
4189
4263
  divided: Boolean,
4264
+ direction: {
4265
+ type: String,
4266
+ default: 'horizontal'
4267
+ },
4190
4268
  ...makeBorderProps(),
4191
4269
  ...makeComponentProps(),
4192
4270
  ...makeDensityProps(),
@@ -4220,7 +4298,7 @@
4220
4298
  } = useRounded(props);
4221
4299
  provideDefaults({
4222
4300
  VBtn: {
4223
- height: 'auto',
4301
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4224
4302
  baseColor: vue.toRef(() => props.baseColor),
4225
4303
  color: vue.toRef(() => props.color),
4226
4304
  density: vue.toRef(() => props.density),
@@ -4230,7 +4308,7 @@
4230
4308
  });
4231
4309
  useRender(() => {
4232
4310
  return vue.createVNode(props.tag, {
4233
- "class": vue.normalizeClass(['v-btn-group', {
4311
+ "class": vue.normalizeClass(['v-btn-group', `v-btn-group--${props.direction}`, {
4234
4312
  'v-btn-group--divided': props.divided
4235
4313
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
4236
4314
  "style": vue.normalizeStyle(props.style)
@@ -5562,8 +5640,8 @@
5562
5640
  window.clearTimeout(element._ripple.showTimer);
5563
5641
  }
5564
5642
  let keyboardRipple = false;
5565
- function keyboardRippleShow(e) {
5566
- if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
5643
+ function keyboardRippleShow(e, keys) {
5644
+ if (!keyboardRipple && keys.includes(e.keyCode)) {
5567
5645
  keyboardRipple = true;
5568
5646
  rippleShow(e);
5569
5647
  }
@@ -5591,9 +5669,12 @@
5591
5669
  el._ripple.enabled = enabled;
5592
5670
  el._ripple.centered = modifiers.center;
5593
5671
  el._ripple.circle = modifiers.circle;
5594
- if (isObject(value) && value.class) {
5595
- el._ripple.class = value.class;
5672
+ const bindingValue = isObject(value) ? value : {};
5673
+ if (bindingValue.class) {
5674
+ el._ripple.class = bindingValue.class;
5596
5675
  }
5676
+ const allowedKeys = bindingValue.keys ?? [keyCodes.enter, keyCodes.space];
5677
+ el._ripple.keyDownHandler = e => keyboardRippleShow(e, allowedKeys);
5597
5678
  if (enabled && !wasEnabled) {
5598
5679
  if (modifiers.stop) {
5599
5680
  el.addEventListener('touchstart', rippleStop, {
@@ -5615,7 +5696,7 @@
5615
5696
  el.addEventListener('mousedown', rippleShow);
5616
5697
  el.addEventListener('mouseup', rippleHide);
5617
5698
  el.addEventListener('mouseleave', rippleHide);
5618
- el.addEventListener('keydown', keyboardRippleShow);
5699
+ el.addEventListener('keydown', e => keyboardRippleShow(e, allowedKeys));
5619
5700
  el.addEventListener('keyup', keyboardRippleHide);
5620
5701
  el.addEventListener('blur', focusRippleHide);
5621
5702
 
@@ -5635,7 +5716,9 @@
5635
5716
  el.removeEventListener('touchcancel', rippleHide);
5636
5717
  el.removeEventListener('mouseup', rippleHide);
5637
5718
  el.removeEventListener('mouseleave', rippleHide);
5638
- el.removeEventListener('keydown', keyboardRippleShow);
5719
+ if (el._ripple?.keyDownHandler) {
5720
+ el.removeEventListener('keydown', el._ripple.keyDownHandler);
5721
+ }
5639
5722
  el.removeEventListener('keyup', keyboardRippleHide);
5640
5723
  el.removeEventListener('dragstart', rippleHide);
5641
5724
  el.removeEventListener('blur', focusRippleHide);
@@ -5644,8 +5727,8 @@
5644
5727
  updateRipple(el, binding, false);
5645
5728
  }
5646
5729
  function unmounted$4(el) {
5647
- delete el._ripple;
5648
5730
  removeListeners(el);
5731
+ delete el._ripple;
5649
5732
  }
5650
5733
  function updated$1(el, binding) {
5651
5734
  if (binding.value === binding.oldValue) {
@@ -5918,6 +6001,31 @@
5918
6001
  // Utilities
5919
6002
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5920
6003
 
6004
+ // Utilities
6005
+
6006
+ // Types
6007
+
6008
+ // Types
6009
+
6010
+ // Composables
6011
+ const makeIconSizeProps = propsFactory({
6012
+ iconSize: [Number, String],
6013
+ iconSizes: {
6014
+ type: Array,
6015
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6016
+ }
6017
+ }, 'iconSize');
6018
+ function useIconSizes(props, fallback) {
6019
+ const iconSize = vue.computed(() => {
6020
+ const iconSizeMap = new Map(props.iconSizes);
6021
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6022
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6023
+ });
6024
+ return {
6025
+ iconSize
6026
+ };
6027
+ }
6028
+
5921
6029
  // Types
5922
6030
 
5923
6031
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5957,6 +6065,7 @@
5957
6065
  ...makeDensityProps(),
5958
6066
  ...makeDimensionProps(),
5959
6067
  ...makeElevationProps(),
6068
+ ...makeIconSizeProps(),
5960
6069
  ...makeLocationProps(),
5961
6070
  ...makePositionProps(),
5962
6071
  ...makeRoundedProps(),
@@ -5984,6 +6093,9 @@
5984
6093
  if (!props.type) return props.icon;
5985
6094
  return props.icon ?? `$${props.type}`;
5986
6095
  });
6096
+ const {
6097
+ iconSize
6098
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5987
6099
  const {
5988
6100
  themeClasses
5989
6101
  } = provideTheme(props);
@@ -6031,6 +6143,11 @@
6031
6143
  const hasPrepend = !!(slots.prepend || icon.value);
6032
6144
  const hasTitle = !!(slots.title || props.title);
6033
6145
  const hasClose = !!(slots.close || props.closable);
6146
+ const iconProps = {
6147
+ density: props.density,
6148
+ icon: icon.value,
6149
+ size: iconSize.value
6150
+ };
6034
6151
  return isActive.value && vue.createVNode(props.tag, {
6035
6152
  "class": vue.normalizeClass(['v-alert', props.border && {
6036
6153
  'v-alert--border': !!props.border,
@@ -6048,19 +6165,14 @@
6048
6165
  }, null), hasPrepend && vue.createElementVNode("div", {
6049
6166
  "key": "prepend",
6050
6167
  "class": "v-alert__prepend"
6051
- }, [!slots.prepend ? vue.createVNode(VIcon, {
6052
- "key": "prepend-icon",
6053
- "density": props.density,
6054
- "icon": icon.value,
6055
- "size": props.prominent ? 44 : 28
6056
- }, null) : vue.createVNode(VDefaultsProvider, {
6168
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6169
+ "key": "prepend-icon"
6170
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6057
6171
  "key": "prepend-defaults",
6058
6172
  "disabled": !icon.value,
6059
6173
  "defaults": {
6060
6174
  VIcon: {
6061
- density: props.density,
6062
- icon: icon.value,
6063
- size: props.prominent ? 44 : 28
6175
+ ...iconProps
6064
6176
  }
6065
6177
  }
6066
6178
  }, slots.prepend)]), vue.createElementVNode("div", {
@@ -7585,6 +7697,7 @@
7585
7697
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7586
7698
  const makeVSlideGroupProps = propsFactory({
7587
7699
  centerActive: Boolean,
7700
+ contentClass: null,
7588
7701
  direction: {
7589
7702
  type: String,
7590
7703
  default: 'horizontal'
@@ -7897,7 +8010,7 @@
7897
8010
  })]), vue.createElementVNode("div", {
7898
8011
  "key": "container",
7899
8012
  "ref": containerRef,
7900
- "class": "v-slide-group__container",
8013
+ "class": vue.normalizeClass(['v-slide-group__container', props.contentClass]),
7901
8014
  "onScroll": onScroll
7902
8015
  }, [vue.createElementVNode("div", {
7903
8016
  "ref": contentRef,
@@ -8260,16 +8373,85 @@
8260
8373
  }
8261
8374
  });
8262
8375
 
8376
+ const makeVDividerProps = propsFactory({
8377
+ color: String,
8378
+ inset: Boolean,
8379
+ length: [Number, String],
8380
+ opacity: [Number, String],
8381
+ thickness: [Number, String],
8382
+ vertical: Boolean,
8383
+ ...makeComponentProps(),
8384
+ ...makeThemeProps()
8385
+ }, 'VDivider');
8386
+ const VDivider = genericComponent()({
8387
+ name: 'VDivider',
8388
+ props: makeVDividerProps(),
8389
+ setup(props, _ref) {
8390
+ let {
8391
+ attrs,
8392
+ slots
8393
+ } = _ref;
8394
+ const {
8395
+ themeClasses
8396
+ } = provideTheme(props);
8397
+ const {
8398
+ textColorClasses,
8399
+ textColorStyles
8400
+ } = useTextColor(() => props.color);
8401
+ const dividerStyles = vue.computed(() => {
8402
+ const styles = {};
8403
+ if (props.length) {
8404
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8405
+ }
8406
+ if (props.thickness) {
8407
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8408
+ }
8409
+ return styles;
8410
+ });
8411
+ useRender(() => {
8412
+ const divider = vue.createElementVNode("hr", {
8413
+ "class": vue.normalizeClass([{
8414
+ 'v-divider': true,
8415
+ 'v-divider--inset': props.inset,
8416
+ 'v-divider--vertical': props.vertical
8417
+ }, themeClasses.value, textColorClasses.value, props.class]),
8418
+ "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
8419
+ '--v-border-opacity': props.opacity
8420
+ }, props.style]),
8421
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8422
+ "role": `${attrs.role || 'separator'}`
8423
+ }, null);
8424
+ if (!slots.default) return divider;
8425
+ return vue.createElementVNode("div", {
8426
+ "class": vue.normalizeClass(['v-divider__wrapper', {
8427
+ 'v-divider__wrapper--vertical': props.vertical,
8428
+ 'v-divider__wrapper--inset': props.inset
8429
+ }])
8430
+ }, [divider, vue.createElementVNode("div", {
8431
+ "class": "v-divider__content"
8432
+ }, [slots.default()]), divider]);
8433
+ });
8434
+ return {};
8435
+ }
8436
+ });
8437
+
8263
8438
  // Utilities
8264
8439
 
8265
8440
  // List
8266
8441
  const ListKey = Symbol.for('vuetify:list');
8267
8442
  function createList() {
8443
+ let {
8444
+ filterable
8445
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
8446
+ filterable: false
8447
+ };
8268
8448
  const parent = vue.inject(ListKey, {
8449
+ filterable: false,
8269
8450
  hasPrepend: vue.shallowRef(false),
8270
8451
  updateHasPrepend: () => null
8271
8452
  });
8272
8453
  const data = {
8454
+ filterable: parent.filterable || filterable,
8273
8455
  hasPrepend: vue.shallowRef(false),
8274
8456
  updateHasPrepend: value => {
8275
8457
  if (value) data.hasPrepend.value = value;
@@ -9221,6 +9403,9 @@
9221
9403
  roundedClasses
9222
9404
  } = useRounded(roundedProps);
9223
9405
  const lineClasses = vue.toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
9406
+ const rippleOptions = vue.toRef(() => props.ripple !== undefined && !!props.ripple && list?.filterable ? {
9407
+ keys: [keyCodes.enter]
9408
+ } : props.ripple);
9224
9409
  const slotProps = vue.computed(() => ({
9225
9410
  isActive: isActive.value,
9226
9411
  select,
@@ -9245,8 +9430,9 @@
9245
9430
  function onKeyDown(e) {
9246
9431
  const target = e.target;
9247
9432
  if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
9248
- if (e.key === 'Enter' || e.key === ' ') {
9433
+ if (e.key === 'Enter' || e.key === ' ' && !list?.filterable) {
9249
9434
  e.preventDefault();
9435
+ e.stopPropagation();
9250
9436
  e.target.dispatchEvent(new MouseEvent('click', e));
9251
9437
  }
9252
9438
  }
@@ -9356,7 +9542,7 @@
9356
9542
  }), vue.createElementVNode("div", {
9357
9543
  "class": "v-list-item__spacer"
9358
9544
  }, null)])]
9359
- }), [[Ripple, isClickable.value && props.ripple]]);
9545
+ }), [[Ripple, isClickable.value && rippleOptions.value]]);
9360
9546
  });
9361
9547
  return {
9362
9548
  activate,
@@ -9411,68 +9597,6 @@
9411
9597
  }
9412
9598
  });
9413
9599
 
9414
- const makeVDividerProps = propsFactory({
9415
- color: String,
9416
- inset: Boolean,
9417
- length: [Number, String],
9418
- opacity: [Number, String],
9419
- thickness: [Number, String],
9420
- vertical: Boolean,
9421
- ...makeComponentProps(),
9422
- ...makeThemeProps()
9423
- }, 'VDivider');
9424
- const VDivider = genericComponent()({
9425
- name: 'VDivider',
9426
- props: makeVDividerProps(),
9427
- setup(props, _ref) {
9428
- let {
9429
- attrs,
9430
- slots
9431
- } = _ref;
9432
- const {
9433
- themeClasses
9434
- } = provideTheme(props);
9435
- const {
9436
- textColorClasses,
9437
- textColorStyles
9438
- } = useTextColor(() => props.color);
9439
- const dividerStyles = vue.computed(() => {
9440
- const styles = {};
9441
- if (props.length) {
9442
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9443
- }
9444
- if (props.thickness) {
9445
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9446
- }
9447
- return styles;
9448
- });
9449
- useRender(() => {
9450
- const divider = vue.createElementVNode("hr", {
9451
- "class": vue.normalizeClass([{
9452
- 'v-divider': true,
9453
- 'v-divider--inset': props.inset,
9454
- 'v-divider--vertical': props.vertical
9455
- }, themeClasses.value, textColorClasses.value, props.class]),
9456
- "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
9457
- '--v-border-opacity': props.opacity
9458
- }, props.style]),
9459
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9460
- "role": `${attrs.role || 'separator'}`
9461
- }, null);
9462
- if (!slots.default) return divider;
9463
- return vue.createElementVNode("div", {
9464
- "class": vue.normalizeClass(['v-divider__wrapper', {
9465
- 'v-divider__wrapper--vertical': props.vertical,
9466
- 'v-divider__wrapper--inset': props.inset
9467
- }])
9468
- }, [divider, vue.createElementVNode("div", {
9469
- "class": "v-divider__content"
9470
- }, [slots.default()]), divider]);
9471
- });
9472
- return {};
9473
- }
9474
- });
9475
-
9476
9600
  // Types
9477
9601
 
9478
9602
  const makeVListChildrenProps = propsFactory({
@@ -9741,6 +9865,7 @@
9741
9865
  activeClass: String,
9742
9866
  bgColor: String,
9743
9867
  disabled: Boolean,
9868
+ filterable: Boolean,
9744
9869
  expandIcon: IconValue,
9745
9870
  collapseIcon: IconValue,
9746
9871
  lines: {
@@ -9824,7 +9949,9 @@
9824
9949
  const activeColor = vue.toRef(() => props.activeColor);
9825
9950
  const baseColor = vue.toRef(() => props.baseColor);
9826
9951
  const color = vue.toRef(() => props.color);
9827
- createList();
9952
+ createList({
9953
+ filterable: props.filterable
9954
+ });
9828
9955
  provideDefaults({
9829
9956
  VListGroup: {
9830
9957
  activeColor,
@@ -12401,7 +12528,12 @@
12401
12528
  }
12402
12529
  function calculateOffset(index) {
12403
12530
  index = clamp(index, 0, items.value.length - 1);
12404
- 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;
12405
12537
  }
12406
12538
  function calculateIndex(scrollTop) {
12407
12539
  return binaryClosest(offsets, scrollTop);
@@ -12755,6 +12887,7 @@
12755
12887
  },
12756
12888
  openOnClear: Boolean,
12757
12889
  itemColor: String,
12890
+ noAutoScroll: Boolean,
12758
12891
  ...makeItemsProps({
12759
12892
  itemChildren: false
12760
12893
  })
@@ -12969,7 +13102,7 @@
12969
13102
  vue.watch(menu, () => {
12970
13103
  if (!props.hideSelected && menu.value && model.value.length) {
12971
13104
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
12972
- IN_BROWSER && window.requestAnimationFrame(() => {
13105
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
12973
13106
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
12974
13107
  });
12975
13108
  }
@@ -13062,6 +13195,22 @@
13062
13195
  key: item.value,
13063
13196
  onClick: () => select(item, null)
13064
13197
  });
13198
+ if (item.raw.type === 'divider') {
13199
+ return slots.divider?.({
13200
+ props: item.raw,
13201
+ index
13202
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13203
+ "key": `divider-${index}`
13204
+ }), null);
13205
+ }
13206
+ if (item.raw.type === 'subheader') {
13207
+ return slots.subheader?.({
13208
+ props: item.raw,
13209
+ index
13210
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13211
+ "key": `subheader-${index}`
13212
+ }), null);
13213
+ }
13065
13214
  return slots.item?.({
13066
13215
  item,
13067
13216
  index,
@@ -13222,6 +13371,9 @@
13222
13371
  let match = -1;
13223
13372
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13224
13373
  if (typeof item === 'object') {
13374
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13375
+ continue;
13376
+ }
13225
13377
  const filterKeys = keys || Object.keys(transformed);
13226
13378
  for (const key of filterKeys) {
13227
13379
  const value = getPropertyFromItem(transformed, key);
@@ -13424,7 +13576,7 @@
13424
13576
  menu.value = !menu.value;
13425
13577
  }
13426
13578
  function onListKeydown(e) {
13427
- if (e.key !== ' ' && checkPrintable(e)) {
13579
+ if (checkPrintable(e) || e.key === 'Backspace') {
13428
13580
  vTextFieldRef.value?.focus();
13429
13581
  }
13430
13582
  }
@@ -13629,6 +13781,7 @@
13629
13781
  }, props.menuProps), {
13630
13782
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
13631
13783
  "ref": listRef,
13784
+ "filterable": true,
13632
13785
  "selected": selectedValues.value,
13633
13786
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
13634
13787
  "onMousedown": e => e.preventDefault(),
@@ -13660,6 +13813,22 @@
13660
13813
  active: highlightFirst.value && index === 0 ? true : undefined,
13661
13814
  onClick: () => select(item, null)
13662
13815
  });
13816
+ if (item.raw.type === 'divider') {
13817
+ return slots.divider?.({
13818
+ props: item.raw,
13819
+ index
13820
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13821
+ "key": `divider-${index}`
13822
+ }), null);
13823
+ }
13824
+ if (item.raw.type === 'subheader') {
13825
+ return slots.subheader?.({
13826
+ props: item.raw,
13827
+ index
13828
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13829
+ "key": `subheader-${index}`
13830
+ }), null);
13831
+ }
13663
13832
  return slots.item?.({
13664
13833
  item,
13665
13834
  index,
@@ -13804,7 +13973,8 @@
13804
13973
  ...makeThemeProps(),
13805
13974
  ...makeTransitionProps({
13806
13975
  transition: 'scale-rotate-transition'
13807
- })
13976
+ }),
13977
+ ...makeDimensionProps()
13808
13978
  }, 'VBadge');
13809
13979
  const VBadge = genericComponent()({
13810
13980
  name: 'VBadge',
@@ -13834,6 +14004,9 @@
13834
14004
  const base = props.floating ? props.dot ? 2 : 4 : props.dot ? 8 : 12;
13835
14005
  return base + (['top', 'bottom'].includes(side) ? Number(props.offsetY ?? 0) : ['left', 'right'].includes(side) ? Number(props.offsetX ?? 0) : 0);
13836
14006
  });
14007
+ const {
14008
+ dimensionStyles
14009
+ } = useDimension(props);
13837
14010
  useRender(() => {
13838
14011
  const value = Number(props.content);
13839
14012
  const content = !props.max || isNaN(value) ? props.content : value <= Number(props.max) ? value : `${props.max}+`;
@@ -13855,7 +14028,7 @@
13855
14028
  }, {
13856
14029
  default: () => [vue.withDirectives(vue.createElementVNode("span", vue.mergeProps({
13857
14030
  "class": ['v-badge__badge', themeClasses.value, backgroundColorClasses.value, roundedClasses.value, textColorClasses.value],
13858
- "style": [backgroundColorStyles.value, textColorStyles.value, props.inline ? {} : locationStyles.value],
14031
+ "style": [backgroundColorStyles.value, textColorStyles.value, dimensionStyles.value, props.inline ? {} : locationStyles.value],
13859
14032
  "aria-atomic": "true",
13860
14033
  "aria-label": t(props.label, value),
13861
14034
  "aria-live": "polite",
@@ -17264,13 +17437,13 @@
17264
17437
  return null;
17265
17438
  }
17266
17439
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17267
- function getWeekdays(locale, firstDayOfWeek) {
17440
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17268
17441
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17269
17442
  return createRange(7).map(i => {
17270
17443
  const weekday = new Date(sundayJanuarySecond2000);
17271
17444
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17272
17445
  return new Intl.DateTimeFormat(locale, {
17273
- weekday: 'narrow'
17446
+ weekday: weekdayFormat ?? 'narrow'
17274
17447
  }).format(weekday);
17275
17448
  });
17276
17449
  }
@@ -17734,9 +17907,9 @@
17734
17907
  getDiff(date, comparing, unit) {
17735
17908
  return getDiff(date, comparing, unit);
17736
17909
  }
17737
- getWeekdays(firstDayOfWeek) {
17910
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17738
17911
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17739
- return getWeekdays(this.locale, firstDay);
17912
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17740
17913
  }
17741
17914
  getYear(date) {
17742
17915
  return getYear(date);
@@ -18091,6 +18264,7 @@
18091
18264
  _search.value = val ?? '';
18092
18265
  if (!props.multiple && !hasSelectionSlot.value) {
18093
18266
  model.value = [transformItem$3(props, val)];
18267
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18094
18268
  }
18095
18269
  if (val && props.multiple && props.delimiters?.length) {
18096
18270
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18171,7 +18345,7 @@
18171
18345
  menu.value = !menu.value;
18172
18346
  }
18173
18347
  function onListKeydown(e) {
18174
- if (e.key !== ' ' && checkPrintable(e)) {
18348
+ if (checkPrintable(e) || e.key === 'Backspace') {
18175
18349
  vTextFieldRef.value?.focus();
18176
18350
  }
18177
18351
  }
@@ -18376,6 +18550,7 @@
18376
18550
  }, props.menuProps), {
18377
18551
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18378
18552
  "ref": listRef,
18553
+ "filterable": true,
18379
18554
  "selected": selectedValues.value,
18380
18555
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18381
18556
  "onMousedown": e => e.preventDefault(),
@@ -18407,6 +18582,22 @@
18407
18582
  active: highlightFirst.value && index === 0 ? true : undefined,
18408
18583
  onClick: () => select(item, null)
18409
18584
  });
18585
+ if (item.raw.type === 'divider') {
18586
+ return slots.divider?.({
18587
+ props: item.raw,
18588
+ index
18589
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18590
+ "key": `divider-${index}`
18591
+ }), null);
18592
+ }
18593
+ if (item.raw.type === 'subheader') {
18594
+ return slots.subheader?.({
18595
+ props: item.raw,
18596
+ index
18597
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18598
+ "key": `subheader-${index}`
18599
+ }), null);
18600
+ }
18410
18601
  return slots.item?.({
18411
18602
  item,
18412
18603
  index,
@@ -20289,6 +20480,7 @@
20289
20480
  color: String,
20290
20481
  disableSort: Boolean,
20291
20482
  fixedHeader: Boolean,
20483
+ lastFixed: Boolean,
20292
20484
  multiSort: Boolean,
20293
20485
  sortAscIcon: {
20294
20486
  type: IconValue,
@@ -20335,10 +20527,11 @@
20335
20527
  loaderClasses
20336
20528
  } = useLoader(props);
20337
20529
  function getFixedStyles(column, y) {
20338
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20530
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20339
20531
  return {
20340
20532
  position: 'sticky',
20341
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20533
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20534
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20342
20535
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20343
20536
  };
20344
20537
  }
@@ -20854,11 +21047,18 @@
20854
21047
  }
20855
21048
  });
20856
21049
 
21050
+ // Types
21051
+
20857
21052
  const makeVTableProps = propsFactory({
20858
21053
  fixedHeader: Boolean,
20859
21054
  fixedFooter: Boolean,
20860
21055
  height: [Number, String],
20861
21056
  hover: Boolean,
21057
+ striped: {
21058
+ type: String,
21059
+ default: null,
21060
+ validator: v => ['even', 'odd'].includes(v)
21061
+ },
20862
21062
  ...makeComponentProps(),
20863
21063
  ...makeDensityProps(),
20864
21064
  ...makeTagProps(),
@@ -20885,7 +21085,9 @@
20885
21085
  'v-table--fixed-footer': props.fixedFooter,
20886
21086
  'v-table--has-top': !!slots.top,
20887
21087
  'v-table--has-bottom': !!slots.bottom,
20888
- 'v-table--hover': props.hover
21088
+ 'v-table--hover': props.hover,
21089
+ 'v-table--striped-even': props.striped === 'even',
21090
+ 'v-table--striped-odd': props.striped === 'odd'
20889
21091
  }, themeClasses.value, densityClasses.value, props.class]),
20890
21092
  "style": vue.normalizeStyle(props.style)
20891
21093
  }, {
@@ -22060,7 +22262,8 @@
22060
22262
  firstDayOfWeek: {
22061
22263
  type: [Number, String],
22062
22264
  default: undefined
22063
- }
22265
+ },
22266
+ weekdayFormat: String
22064
22267
  }, 'calendar');
22065
22268
  function useCalendar(props) {
22066
22269
  const adapter = useDate();
@@ -22301,7 +22504,7 @@
22301
22504
  "ref": daysRef,
22302
22505
  "key": daysInMonth.value[0].date?.toString(),
22303
22506
  "class": "v-date-picker-month__days"
22304
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => vue.createElementVNode("div", {
22507
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => vue.createElementVNode("div", {
22305
22508
  "class": vue.normalizeClass(['v-date-picker-month__day', 'v-date-picker-month__weekday'])
22306
22509
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22307
22510
  const slotProps = {
@@ -23916,6 +24119,9 @@
23916
24119
  startStatus.value = status;
23917
24120
  } else if (side === 'end') {
23918
24121
  endStatus.value = status;
24122
+ } else if (side === 'both') {
24123
+ startStatus.value = status;
24124
+ endStatus.value = status;
23919
24125
  }
23920
24126
  }
23921
24127
  function getStatus(side) {
@@ -24027,6 +24233,32 @@
24027
24233
  }, [renderSide('end', endStatus.value)])]
24028
24234
  });
24029
24235
  });
24236
+ function reset(side) {
24237
+ const effectiveSide = side ?? props.side;
24238
+ setStatus(effectiveSide, 'ok');
24239
+ vue.nextTick(() => {
24240
+ setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
24241
+ if (props.mode !== 'manual') {
24242
+ vue.nextTick(() => {
24243
+ window.requestAnimationFrame(() => {
24244
+ window.requestAnimationFrame(() => {
24245
+ window.requestAnimationFrame(() => {
24246
+ if (effectiveSide === 'both') {
24247
+ intersecting('start');
24248
+ intersecting('end');
24249
+ } else {
24250
+ intersecting(effectiveSide);
24251
+ }
24252
+ });
24253
+ });
24254
+ });
24255
+ });
24256
+ }
24257
+ });
24258
+ }
24259
+ return {
24260
+ reset
24261
+ };
24030
24262
  }
24031
24263
  });
24032
24264
 
@@ -24945,6 +25177,10 @@
24945
25177
  type: Number,
24946
25178
  default: 0
24947
25179
  },
25180
+ minFractionDigits: {
25181
+ type: Number,
25182
+ default: null
25183
+ },
24948
25184
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24949
25185
  }, 'VNumberInput');
24950
25186
  const VNumberInput = genericComponent()({
@@ -24972,9 +25208,19 @@
24972
25208
  const isFocused = vue.shallowRef(props.focused);
24973
25209
  function correctPrecision(val) {
24974
25210
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
24975
- const fixed = precision == null ? String(val) : val.toFixed(precision);
24976
- return isFocused.value ? Number(fixed).toString() // trim zeros
24977
- : fixed;
25211
+ if (precision == null) {
25212
+ return String(val);
25213
+ }
25214
+ let fixed = val.toFixed(precision);
25215
+ if (isFocused.value) {
25216
+ return Number(fixed).toString(); // trim zeros
25217
+ }
25218
+ if ((props.minFractionDigits ?? precision) < precision) {
25219
+ const trimLimit = precision - props.minFractionDigits;
25220
+ const [baseDigits, fractionDigits] = fixed.split('.');
25221
+ fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
25222
+ }
25223
+ return fixed;
24978
25224
  }
24979
25225
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24980
25226
  const _inputText = vue.shallowRef(null);
@@ -25029,6 +25275,7 @@
25029
25275
  }
25030
25276
  };
25031
25277
  vue.watch(() => props.precision, () => formatInputValue());
25278
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
25032
25279
  vue.onMounted(() => {
25033
25280
  clampModel();
25034
25281
  });
@@ -25143,7 +25390,7 @@
25143
25390
  inputText.value = null;
25144
25391
  return;
25145
25392
  }
25146
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25393
+ inputText.value = correctPrecision(model.value);
25147
25394
  }
25148
25395
  function trimDecimalZeros() {
25149
25396
  if (controlsDisabled.value) return;
@@ -25403,9 +25650,10 @@
25403
25650
  e.preventDefault();
25404
25651
  e.stopPropagation();
25405
25652
  const clipboardText = e?.clipboardData?.getData('Text').trim().slice(0, length.value) ?? '';
25653
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25406
25654
  if (isValidNumber(clipboardText)) return;
25407
25655
  model.value = clipboardText.split('');
25408
- inputRef.value?.[index].blur();
25656
+ inputRef.value?.[finalIndex].focus();
25409
25657
  }
25410
25658
  function reset() {
25411
25659
  model.value = [];
@@ -30105,11 +30353,6 @@
30105
30353
  hideOverlay: Boolean,
30106
30354
  icon: [String, Function, Object],
30107
30355
  iconColor: String,
30108
- iconSize: [Number, String],
30109
- iconSizes: {
30110
- type: Array,
30111
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
30112
- },
30113
30356
  loading: Boolean,
30114
30357
  opacity: [Number, String],
30115
30358
  readonly: Boolean,
@@ -30129,6 +30372,7 @@
30129
30372
  ...makeBorderProps(),
30130
30373
  ...makeComponentProps(),
30131
30374
  ...makeElevationProps(),
30375
+ ...makeIconSizeProps(),
30132
30376
  ...makeRoundedProps(),
30133
30377
  ...makeTagProps({
30134
30378
  tag: 'button'
@@ -30183,7 +30427,6 @@
30183
30427
  })()
30184
30428
  }));
30185
30429
  const btnSizeMap = new Map(props.sizes);
30186
- const iconSizeMap = new Map(props.iconSizes);
30187
30430
  function onClick() {
30188
30431
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
30189
30432
  isActive.value = !isActive.value;
@@ -30195,12 +30438,12 @@
30195
30438
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
30196
30439
  const btnHeight = props.height ?? btnSize;
30197
30440
  const btnWidth = props.width ?? btnSize;
30198
- const _iconSize = props.iconSize;
30199
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
30200
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30441
+ const {
30442
+ iconSize
30443
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
30201
30444
  const iconProps = {
30202
30445
  icon,
30203
- size: iconSize,
30446
+ size: iconSize.value,
30204
30447
  iconColor: props.iconColor,
30205
30448
  opacity: props.opacity
30206
30449
  };
@@ -30243,7 +30486,7 @@
30243
30486
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30244
30487
  "indeterminate": "disable-shrink",
30245
30488
  "width": "2",
30246
- "size": iconSize
30489
+ "size": iconSize.value
30247
30490
  }, null)])]
30248
30491
  });
30249
30492
  });
@@ -30251,6 +30494,251 @@
30251
30494
  }
30252
30495
  });
30253
30496
 
30497
+ // Utilities
30498
+
30499
+ // Types
30500
+
30501
+ const makeMaskProps = propsFactory({
30502
+ mask: [String, Object],
30503
+ returnMaskedValue: Boolean
30504
+ }, 'mask');
30505
+ const defaultDelimiters = /[-!$%^&*()_+|~=`{}[\]:";'<>?,./\\ ]/;
30506
+ const presets = {
30507
+ 'credit-card': '#### - #### - #### - ####',
30508
+ date: '##/##/####',
30509
+ 'date-time': '##/##/#### ##:##',
30510
+ 'iso-date': '####-##-##',
30511
+ 'iso-date-time': '####-##-## ##:##',
30512
+ phone: '(###) ### - ####',
30513
+ social: '###-##-####',
30514
+ time: '##:##',
30515
+ 'time-with-seconds': '##:##:##'
30516
+ };
30517
+ function isMaskDelimiter(char) {
30518
+ return char ? defaultDelimiters.test(char) : false;
30519
+ }
30520
+ const defaultTokens = {
30521
+ '#': {
30522
+ pattern: /[0-9]/
30523
+ },
30524
+ A: {
30525
+ pattern: /[A-Z]/i,
30526
+ convert: v => v.toUpperCase()
30527
+ },
30528
+ a: {
30529
+ pattern: /[a-z]/i,
30530
+ convert: v => v.toLowerCase()
30531
+ },
30532
+ N: {
30533
+ pattern: /[0-9A-Z]/i,
30534
+ convert: v => v.toUpperCase()
30535
+ },
30536
+ n: {
30537
+ pattern: /[0-9a-z]/i,
30538
+ convert: v => v.toLowerCase()
30539
+ },
30540
+ X: {
30541
+ pattern: defaultDelimiters
30542
+ }
30543
+ };
30544
+ function useMask(props, inputRef) {
30545
+ const mask = vue.computed(() => {
30546
+ if (typeof props.mask === 'string') {
30547
+ if (props.mask in presets) return presets[props.mask];
30548
+ return props.mask;
30549
+ }
30550
+ return props.mask?.mask ?? '';
30551
+ });
30552
+ const tokens = vue.computed(() => {
30553
+ return {
30554
+ ...defaultTokens,
30555
+ ...(isObject(props.mask) ? props.mask.tokens : null)
30556
+ };
30557
+ });
30558
+ const selection = vue.shallowRef(0);
30559
+ const lazySelection = vue.shallowRef(0);
30560
+ function isMask(char) {
30561
+ return char in tokens.value;
30562
+ }
30563
+ function maskValidates(mask, char) {
30564
+ if (char == null || !isMask(mask)) return false;
30565
+ const item = tokens.value[mask];
30566
+ if (item.pattern) return item.pattern.test(char);
30567
+ return item.test(char);
30568
+ }
30569
+ function convert(mask, char) {
30570
+ const item = tokens.value[mask];
30571
+ return item.convert ? item.convert(char) : char;
30572
+ }
30573
+ function maskText(text) {
30574
+ const trimmedText = text?.trim().replace(/\s+/g, ' ');
30575
+ if (trimmedText == null) return '';
30576
+ if (!mask.value.length || !trimmedText.length) return trimmedText;
30577
+ let textIndex = 0;
30578
+ let maskIndex = 0;
30579
+ let newText = '';
30580
+ while (maskIndex < mask.value.length) {
30581
+ const mchar = mask.value[maskIndex];
30582
+ const tchar = trimmedText[textIndex];
30583
+
30584
+ // Escaped character in mask, the next mask character is inserted
30585
+ if (mchar === '\\') {
30586
+ newText += mask.value[maskIndex + 1];
30587
+ maskIndex += 2;
30588
+ continue;
30589
+ }
30590
+ if (!isMask(mchar)) {
30591
+ newText += mchar;
30592
+ if (tchar === mchar) {
30593
+ textIndex++;
30594
+ }
30595
+ } else if (maskValidates(mchar, tchar)) {
30596
+ newText += convert(mchar, tchar);
30597
+ textIndex++;
30598
+ } else {
30599
+ break;
30600
+ }
30601
+ maskIndex++;
30602
+ }
30603
+ return newText;
30604
+ }
30605
+ function unmaskText(text) {
30606
+ if (text == null) return null;
30607
+ if (!mask.value.length || !text.length) return text;
30608
+ let textIndex = 0;
30609
+ let maskIndex = 0;
30610
+ let newText = '';
30611
+ while (true) {
30612
+ const mchar = mask.value[maskIndex];
30613
+ const tchar = text[textIndex];
30614
+ if (tchar == null) break;
30615
+ if (mchar == null) {
30616
+ newText += tchar;
30617
+ textIndex++;
30618
+ continue;
30619
+ }
30620
+
30621
+ // Escaped character in mask, skip the next input character
30622
+ if (mchar === '\\') {
30623
+ if (tchar === mask.value[maskIndex + 1]) {
30624
+ textIndex++;
30625
+ }
30626
+ maskIndex += 2;
30627
+ continue;
30628
+ }
30629
+ if (maskValidates(mchar, tchar)) {
30630
+ // masked char
30631
+ newText += tchar;
30632
+ textIndex++;
30633
+ maskIndex++;
30634
+ continue;
30635
+ } else if (mchar !== tchar) {
30636
+ // input doesn't match mask, skip forward until it does
30637
+ while (true) {
30638
+ const mchar = mask.value[maskIndex++];
30639
+ if (mchar == null || maskValidates(mchar, tchar)) break;
30640
+ }
30641
+ continue;
30642
+ }
30643
+ textIndex++;
30644
+ maskIndex++;
30645
+ }
30646
+ return newText;
30647
+ }
30648
+ function setCaretPosition(newSelection) {
30649
+ selection.value = newSelection;
30650
+ inputRef.value && inputRef.value.setSelectionRange(selection.value, selection.value);
30651
+ }
30652
+ function resetSelections() {
30653
+ if (!inputRef.value?.selectionEnd) return;
30654
+ selection.value = inputRef.value.selectionEnd;
30655
+ lazySelection.value = 0;
30656
+ for (let index = 0; index < selection.value; index++) {
30657
+ isMaskDelimiter(inputRef.value.value[index]) || lazySelection.value++;
30658
+ }
30659
+ }
30660
+ function updateRange() {
30661
+ if (!inputRef.value) return;
30662
+ resetSelections();
30663
+ let selection = 0;
30664
+ const newValue = inputRef.value.value;
30665
+ if (newValue) {
30666
+ for (let index = 0; index < newValue.length; index++) {
30667
+ if (lazySelection.value <= 0) break;
30668
+ isMaskDelimiter(newValue[index]) || lazySelection.value--;
30669
+ selection++;
30670
+ }
30671
+ }
30672
+ setCaretPosition(selection);
30673
+ }
30674
+ return {
30675
+ updateRange,
30676
+ maskText,
30677
+ unmaskText
30678
+ };
30679
+ }
30680
+
30681
+ // Types
30682
+
30683
+ const makeVMaskInputProps = propsFactory({
30684
+ ...makeVTextFieldProps(),
30685
+ ...makeMaskProps()
30686
+ }, 'VMaskInput');
30687
+ const VMaskInput = genericComponent()({
30688
+ name: 'VMaskInput',
30689
+ props: makeVMaskInputProps(),
30690
+ emits: {
30691
+ 'update:modelValue': val => true
30692
+ },
30693
+ setup(props, _ref) {
30694
+ let {
30695
+ slots,
30696
+ emit
30697
+ } = _ref;
30698
+ const vTextFieldRef = vue.ref();
30699
+ const {
30700
+ maskText,
30701
+ updateRange,
30702
+ unmaskText
30703
+ } = useMask(props, vTextFieldRef);
30704
+ const returnMaskedValue = vue.computed(() => props.mask && props.returnMaskedValue);
30705
+ const model = useProxiedModel(props, 'modelValue', undefined,
30706
+ // Always display masked value in input when mask is applied
30707
+ val => props.mask ? maskText(unmaskText(val)) : val, val => {
30708
+ if (props.mask) {
30709
+ const valueBeforeChange = unmaskText(model.value);
30710
+ // E.g. mask is #-# and the input value is '2-23'
30711
+ // model-value should be enforced to '2-2'
30712
+ const enforcedMaskedValue = maskText(unmaskText(val));
30713
+ const newUnmaskedValue = unmaskText(enforcedMaskedValue);
30714
+ if (newUnmaskedValue === valueBeforeChange) {
30715
+ vTextFieldRef.value.value = enforcedMaskedValue;
30716
+ }
30717
+ val = newUnmaskedValue;
30718
+ updateRange();
30719
+ return returnMaskedValue.value ? maskText(val) : val;
30720
+ }
30721
+ return val;
30722
+ });
30723
+ vue.onBeforeMount(() => {
30724
+ if (props.returnMaskedValue) {
30725
+ emit('update:modelValue', model.value);
30726
+ }
30727
+ });
30728
+ useRender(() => {
30729
+ const textFieldProps = VTextField.filterProps(props);
30730
+ return vue.createVNode(VTextField, vue.mergeProps(textFieldProps, {
30731
+ "modelValue": model.value,
30732
+ "onUpdate:modelValue": $event => model.value = $event,
30733
+ "ref": vTextFieldRef
30734
+ }), {
30735
+ ...slots
30736
+ });
30737
+ });
30738
+ return forwardRefs({}, vTextFieldRef);
30739
+ }
30740
+ });
30741
+
30254
30742
  // Types
30255
30743
 
30256
30744
  const makeVStepperVerticalActionsProps = propsFactory({
@@ -31756,6 +32244,7 @@
31756
32244
  VListSubheader: VListSubheader,
31757
32245
  VLocaleProvider: VLocaleProvider,
31758
32246
  VMain: VMain,
32247
+ VMaskInput: VMaskInput,
31759
32248
  VMenu: VMenu,
31760
32249
  VMessages: VMessages,
31761
32250
  VNavigationDrawer: VNavigationDrawer,
@@ -32153,7 +32642,7 @@
32153
32642
  };
32154
32643
  });
32155
32644
  }
32156
- const version$1 = "3.8.8-master.2025-06-10";
32645
+ const version$1 = "3.8.9-dev.2025-06-12";
32157
32646
  createVuetify$1.version = version$1;
32158
32647
 
32159
32648
  // Vue's inject() can only be used in setup
@@ -32451,7 +32940,7 @@
32451
32940
 
32452
32941
  /* eslint-disable local-rules/sort-imports */
32453
32942
 
32454
- const version = "3.8.8-master.2025-06-10";
32943
+ const version = "3.8.9-dev.2025-06-12";
32455
32944
 
32456
32945
  /* eslint-disable local-rules/sort-imports */
32457
32946