@vuetify/nightly 3.8.9-master.2025-06-14 → 3.8.10-dev.2025-06-18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/CHANGELOG.md +46 -14
  2. package/dist/json/attributes.json +3541 -3137
  3. package/dist/json/importMap-labs.json +30 -26
  4. package/dist/json/importMap.json +174 -174
  5. package/dist/json/tags.json +108 -2
  6. package/dist/json/web-types.json +7295 -5648
  7. package/dist/vuetify-labs.cjs +795 -198
  8. package/dist/vuetify-labs.css +4855 -4806
  9. package/dist/vuetify-labs.d.ts +10430 -3099
  10. package/dist/vuetify-labs.esm.js +796 -199
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +795 -198
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +520 -183
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +2398 -2349
  17. package/dist/vuetify.d.ts +2798 -2091
  18. package/dist/vuetify.esm.js +521 -184
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +520 -183
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1257 -1234
  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 +175 -110
  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.css +3 -0
  39. package/lib/components/VBtn/VBtn.d.ts +20 -10
  40. package/lib/components/VBtn/VBtn.sass +3 -0
  41. package/lib/components/VBtnGroup/VBtnGroup.css +32 -8
  42. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  43. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  44. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  45. package/lib/components/VBtnGroup/VBtnGroup.sass +46 -18
  46. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  47. package/lib/components/VCard/VCard.d.ts +20 -10
  48. package/lib/components/VCheckbox/VCheckbox.d.ts +23 -13
  49. package/lib/components/VCheckbox/VCheckboxBtn.d.ts +20 -10
  50. package/lib/components/VChip/VChip.d.ts +20 -10
  51. package/lib/components/VChipGroup/VChipGroup.d.ts +10 -0
  52. package/lib/components/VCombobox/VCombobox.d.ts +175 -110
  53. package/lib/components/VCombobox/VCombobox.js +22 -3
  54. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  55. package/lib/components/VDataTable/VDataTable.d.ts +60 -0
  56. package/lib/components/VDataTable/VDataTableHeaders.d.ts +13 -0
  57. package/lib/components/VDataTable/VDataTableHeaders.js +4 -2
  58. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  59. package/lib/components/VDataTable/VDataTableServer.d.ts +42 -0
  60. package/lib/components/VDataTable/VDataTableVirtual.d.ts +42 -0
  61. package/lib/components/VDatePicker/VDatePicker.d.ts +80 -5
  62. package/lib/components/VDatePicker/VDatePicker.js +10 -4
  63. package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
  64. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +10 -0
  65. package/lib/components/VDatePicker/VDatePickerMonth.js +1 -1
  66. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  67. package/lib/components/VExpansionPanel/VExpansionPanel.d.ts +20 -10
  68. package/lib/components/VExpansionPanel/VExpansionPanelTitle.d.ts +20 -10
  69. package/lib/components/VExpansionPanel/VExpansionPanels.d.ts +20 -10
  70. package/lib/components/VFab/VFab.d.ts +20 -10
  71. package/lib/components/VField/VField.d.ts +3 -3
  72. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  73. package/lib/components/VInfiniteScroll/VInfiniteScroll.d.ts +9 -3
  74. package/lib/components/VInfiniteScroll/VInfiniteScroll.js +29 -0
  75. package/lib/components/VInfiniteScroll/VInfiniteScroll.js.map +1 -1
  76. package/lib/components/VInput/VInput.d.ts +4 -4
  77. package/lib/components/VKbd/VKbd.css +13 -2
  78. package/lib/components/VKbd/VKbd.d.ts +221 -0
  79. package/lib/components/VKbd/VKbd.js +55 -0
  80. package/lib/components/VKbd/VKbd.js.map +1 -0
  81. package/lib/components/VKbd/VKbd.sass +2 -1
  82. package/lib/components/VKbd/_variables.scss +12 -1
  83. package/lib/components/VKbd/index.d.ts +1 -95
  84. package/lib/components/VKbd/index.js +1 -4
  85. package/lib/components/VKbd/index.js.map +1 -1
  86. package/lib/components/VList/VList.d.ts +13 -0
  87. package/lib/components/VList/VList.js +4 -1
  88. package/lib/components/VList/VList.js.map +1 -1
  89. package/lib/components/VList/VListChildren.js +4 -3
  90. package/lib/components/VList/VListChildren.js.map +1 -1
  91. package/lib/components/VList/VListGroup.d.ts +10 -0
  92. package/lib/components/VList/VListGroup.js +2 -2
  93. package/lib/components/VList/VListGroup.js.map +1 -1
  94. package/lib/components/VList/VListItem.d.ts +28 -10
  95. package/lib/components/VList/VListItem.js +7 -3
  96. package/lib/components/VList/VListItem.js.map +1 -1
  97. package/lib/components/VList/list.d.ts +9 -2
  98. package/lib/components/VList/list.js +7 -0
  99. package/lib/components/VList/list.js.map +1 -1
  100. package/lib/components/VMenu/VMenu.d.ts +13 -0
  101. package/lib/components/VMenu/VMenu.js +2 -1
  102. package/lib/components/VMenu/VMenu.js.map +1 -1
  103. package/lib/components/VNumberInput/VNumberInput.d.ts +114 -89
  104. package/lib/components/VNumberInput/VNumberInput.js +43 -20
  105. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  106. package/lib/components/VOtpInput/VOtpInput.js +19 -2
  107. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  108. package/lib/components/VOverlay/VOverlay.css +1 -1
  109. package/lib/components/VOverlay/_variables.scss +1 -1
  110. package/lib/components/VRadio/VRadio.d.ts +20 -10
  111. package/lib/components/VRadioGroup/VRadioGroup.d.ts +23 -13
  112. package/lib/components/VRangeSlider/VRangeSlider.d.ts +3 -3
  113. package/lib/components/VSelect/VSelect.d.ts +204 -118
  114. package/lib/components/VSelect/VSelect.js +21 -3
  115. package/lib/components/VSelect/VSelect.js.map +1 -1
  116. package/lib/components/VSelectionControl/VSelectionControl.d.ts +20 -10
  117. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.d.ts +28 -14
  118. package/lib/components/VSlideGroup/VSlideGroup.d.ts +10 -0
  119. package/lib/components/VSlideGroup/VSlideGroup.js +2 -1
  120. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  121. package/lib/components/VSlider/VSlider.d.ts +3 -3
  122. package/lib/components/VSlider/VSliderThumb.d.ts +20 -10
  123. package/lib/components/VSpeedDial/VSpeedDial.d.ts +13 -0
  124. package/lib/components/VStepper/VStepperItem.d.ts +28 -14
  125. package/lib/components/VSwitch/VSwitch.d.ts +23 -13
  126. package/lib/components/VTable/VTable.css +6 -0
  127. package/lib/components/VTable/VTable.d.ts +55 -24
  128. package/lib/components/VTable/VTable.js +9 -2
  129. package/lib/components/VTable/VTable.js.map +1 -1
  130. package/lib/components/VTable/VTable.sass +14 -0
  131. package/lib/components/VTable/_variables.scss +1 -0
  132. package/lib/components/VTabs/VTab.d.ts +56 -28
  133. package/lib/components/VTabs/VTabs.d.ts +10 -0
  134. package/lib/components/VTextField/VTextField.d.ts +27 -27
  135. package/lib/components/VTextField/VTextField.js +4 -4
  136. package/lib/components/VTextField/VTextField.js.map +1 -1
  137. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  138. package/lib/components/VTextarea/VTextarea.js +4 -4
  139. package/lib/components/VTextarea/VTextarea.js.map +1 -1
  140. package/lib/components/VToolbar/VToolbar.d.ts +15 -3
  141. package/lib/components/VToolbar/VToolbar.js +6 -3
  142. package/lib/components/VToolbar/VToolbar.js.map +1 -1
  143. package/lib/composables/autofocus.d.ts +7 -0
  144. package/lib/composables/autofocus.js +10 -0
  145. package/lib/composables/autofocus.js.map +1 -0
  146. package/lib/composables/calendar.d.ts +5 -0
  147. package/lib/composables/calendar.js +2 -1
  148. package/lib/composables/calendar.js.map +1 -1
  149. package/lib/composables/date/DateAdapter.d.ts +3 -3
  150. package/lib/composables/date/DateAdapter.js.map +1 -1
  151. package/lib/composables/date/adapters/string.d.ts +54 -0
  152. package/lib/composables/date/adapters/string.js +153 -0
  153. package/lib/composables/date/adapters/string.js.map +1 -0
  154. package/lib/composables/date/adapters/vuetify.d.ts +1 -1
  155. package/lib/composables/date/adapters/vuetify.js +4 -4
  156. package/lib/composables/date/adapters/vuetify.js.map +1 -1
  157. package/lib/composables/date/date.d.ts +3 -3
  158. package/lib/composables/date/index.d.ts +1 -0
  159. package/lib/composables/date/index.js +1 -0
  160. package/lib/composables/date/index.js.map +1 -1
  161. package/lib/composables/filter.js +3 -0
  162. package/lib/composables/filter.js.map +1 -1
  163. package/lib/composables/group.js +1 -0
  164. package/lib/composables/group.js.map +1 -1
  165. package/lib/composables/iconSizes.d.ts +28 -0
  166. package/lib/composables/iconSizes.js +23 -0
  167. package/lib/composables/iconSizes.js.map +1 -0
  168. package/lib/composables/intersectionObserver.js +2 -2
  169. package/lib/composables/intersectionObserver.js.map +1 -1
  170. package/lib/composables/locale.d.ts +5 -1
  171. package/lib/composables/locale.js.map +1 -1
  172. package/lib/composables/mask.d.ts +38 -0
  173. package/lib/composables/mask.js +183 -0
  174. package/lib/composables/mask.js.map +1 -0
  175. package/lib/composables/selectLink.js +2 -2
  176. package/lib/composables/selectLink.js.map +1 -1
  177. package/lib/composables/theme.d.ts +6 -1
  178. package/lib/composables/theme.js +97 -29
  179. package/lib/composables/theme.js.map +1 -1
  180. package/lib/composables/virtual.js +6 -1
  181. package/lib/composables/virtual.js.map +1 -1
  182. package/lib/directives/ripple/index.d.ts +2 -1
  183. package/lib/directives/ripple/index.js +12 -7
  184. package/lib/directives/ripple/index.js.map +1 -1
  185. package/lib/entry-bundler.d.ts +4 -3
  186. package/lib/entry-bundler.js +1 -1
  187. package/lib/entry-bundler.js.map +1 -1
  188. package/lib/framework.d.ts +92 -73
  189. package/lib/framework.js +1 -1
  190. package/lib/framework.js.map +1 -1
  191. package/lib/labs/VCalendar/VCalendar.d.ts +10 -0
  192. package/lib/labs/VColorInput/VColorInput.d.ts +3 -3
  193. package/lib/labs/VDateInput/VDateInput.d.ts +97 -87
  194. package/lib/labs/VFileUpload/VFileUpload.d.ts +3 -3
  195. package/lib/labs/VFileUpload/VFileUploadItem.d.ts +20 -10
  196. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  197. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  198. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  199. package/lib/labs/VMaskInput/VMaskInput.d.ts +6993 -0
  200. package/lib/labs/VMaskInput/VMaskInput.js +67 -0
  201. package/lib/labs/VMaskInput/VMaskInput.js.map +1 -0
  202. package/lib/labs/VMaskInput/index.d.ts +1 -0
  203. package/lib/labs/VMaskInput/index.js +2 -0
  204. package/lib/labs/VMaskInput/index.js.map +1 -0
  205. package/lib/labs/VStepperVertical/VStepperVertical.d.ts +20 -10
  206. package/lib/labs/VStepperVertical/VStepperVerticalItem.d.ts +20 -10
  207. package/lib/labs/VTreeview/VTreeview.d.ts +51 -38
  208. package/lib/labs/VTreeview/VTreeview.js +1 -1
  209. package/lib/labs/VTreeview/VTreeview.js.map +1 -1
  210. package/lib/labs/VTreeview/VTreeviewChildren.d.ts +35 -0
  211. package/lib/labs/VTreeview/VTreeviewChildren.js +21 -3
  212. package/lib/labs/VTreeview/VTreeviewChildren.js.map +1 -1
  213. package/lib/labs/VTreeview/VTreeviewGroup.d.ts +10 -0
  214. package/lib/labs/VTreeview/VTreeviewItem.d.ts +20 -10
  215. package/lib/labs/VTreeview/VTreeviewItem.js +1 -0
  216. package/lib/labs/VTreeview/VTreeviewItem.js.map +1 -1
  217. package/lib/labs/components.d.ts +1 -0
  218. package/lib/labs/components.js +1 -0
  219. package/lib/labs/components.js.map +1 -1
  220. package/lib/labs/entry-bundler.d.ts +4 -3
  221. package/lib/locale/adapters/vue-i18n.js +6 -1
  222. package/lib/locale/adapters/vue-i18n.js.map +1 -1
  223. package/lib/locale/adapters/vuetify.js +7 -1
  224. package/lib/locale/adapters/vuetify.js.map +1 -1
  225. package/lib/util/globals.d.ts +1 -0
  226. package/lib/util/globals.js +1 -0
  227. package/lib/util/globals.js.map +1 -1
  228. package/lib/util/helpers.d.ts +2 -1
  229. package/lib/util/helpers.js +12 -7
  230. package/lib/util/helpers.js.map +1 -1
  231. package/package.json +9 -7
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.9-master.2025-06-14
2
+ * Vuetify v3.8.10-dev.2025-06-18
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"); }
@@ -591,18 +592,23 @@
591
592
  function isPrimitive(value) {
592
593
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint';
593
594
  }
594
- function extractNumber(text, decimalDigitsLimit) {
595
- const cleanText = text.split('').filter(x => /[\d\-.]/.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
595
+ function escapeForRegex(sign) {
596
+ return '\\^$*+?.()|{}[]'.includes(sign) ? `\\${sign}` : sign;
597
+ }
598
+ function extractNumber(text, decimalDigitsLimit, decimalSeparator) {
599
+ const onlyValidCharacters = new RegExp(`[\\d\\-${escapeForRegex(decimalSeparator)}]`);
600
+ const cleanText = text.split('').filter(x => onlyValidCharacters.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
596
601
  // sign allowed at the start
597
- x === '.' && i === all.indexOf('.') ||
602
+ x === decimalSeparator && i === all.indexOf(x) ||
598
603
  // decimal separator allowed only once
599
604
  /\d/.test(x)).join('');
600
605
  if (decimalDigitsLimit === 0) {
601
- return cleanText.split('.')[0];
606
+ return cleanText.split(decimalSeparator)[0];
602
607
  }
603
- if (decimalDigitsLimit !== null && /\.\d/.test(cleanText)) {
604
- const parts = cleanText.split('.');
605
- return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join('.');
608
+ const decimalPart = new RegExp(`${escapeForRegex(decimalSeparator)}\\d`);
609
+ if (decimalDigitsLimit !== null && decimalPart.test(cleanText)) {
610
+ const parts = cleanText.split(decimalSeparator);
611
+ return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join(decimalSeparator);
606
612
  }
607
613
  return cleanText;
608
614
  }
@@ -944,7 +950,7 @@
944
950
  // WoB should always return negative value.
945
951
 
946
952
  const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
947
- outputContrast = SAPC > -1e-3 ? 0.0 : SAPC > -0.078 ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
953
+ outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
948
954
  }
949
955
  return outputContrast * 100;
950
956
  }
@@ -2185,6 +2191,10 @@
2185
2191
  return numberFormat.format(value);
2186
2192
  };
2187
2193
  }
2194
+ function inferDecimalSeparator(current, fallback) {
2195
+ const format = createNumberFunction(current, fallback);
2196
+ return format(0.1).includes(',') ? ',' : '.';
2197
+ }
2188
2198
  function useProvided(props, prop, provided) {
2189
2199
  const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
2190
2200
 
@@ -2207,6 +2217,7 @@
2207
2217
  current,
2208
2218
  fallback,
2209
2219
  messages,
2220
+ decimalSeparator: vue.toRef(() => inferDecimalSeparator(current, fallback)),
2210
2221
  t: createTranslateFunction(current, fallback, messages),
2211
2222
  n: createNumberFunction(current, fallback),
2212
2223
  provide: createProvideFunction({
@@ -2229,6 +2240,7 @@
2229
2240
  current,
2230
2241
  fallback,
2231
2242
  messages,
2243
+ decimalSeparator: vue.toRef(() => options?.decimalSeparator ?? inferDecimalSeparator(current, fallback)),
2232
2244
  t: createTranslateFunction(current, fallback, messages),
2233
2245
  n: createNumberFunction(current, fallback),
2234
2246
  provide: createProvideFunction({
@@ -2355,6 +2367,7 @@
2355
2367
  function genDefaults$2() {
2356
2368
  return {
2357
2369
  defaultTheme: 'light',
2370
+ prefix: 'v-',
2358
2371
  variations: {
2359
2372
  colors: [],
2360
2373
  lighten: 0,
@@ -2392,8 +2405,8 @@
2392
2405
  'activated-opacity': 0.12,
2393
2406
  'pressed-opacity': 0.12,
2394
2407
  'dragged-opacity': 0.08,
2395
- 'theme-kbd': '#212529',
2396
- 'theme-on-kbd': '#FFFFFF',
2408
+ 'theme-kbd': '#EEEEEE',
2409
+ 'theme-on-kbd': '#000000',
2397
2410
  'theme-code': '#F5F5F5',
2398
2411
  'theme-on-code': '#000000'
2399
2412
  }
@@ -2429,14 +2442,17 @@
2429
2442
  'activated-opacity': 0.12,
2430
2443
  'pressed-opacity': 0.16,
2431
2444
  'dragged-opacity': 0.08,
2432
- 'theme-kbd': '#212529',
2445
+ 'theme-kbd': '#424242',
2433
2446
  'theme-on-kbd': '#FFFFFF',
2434
2447
  'theme-code': '#343434',
2435
2448
  'theme-on-code': '#CCCCCC'
2436
2449
  }
2437
2450
  }
2438
2451
  },
2439
- stylesheetId: 'vuetify-theme-stylesheet'
2452
+ stylesheetId: 'vuetify-theme-stylesheet',
2453
+ scoped: false,
2454
+ unimportant: false,
2455
+ utilities: true
2440
2456
  };
2441
2457
  }
2442
2458
  function parseThemeOptions() {
@@ -2459,21 +2475,21 @@
2459
2475
  function createCssClass(lines, selector, content, scope) {
2460
2476
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2461
2477
  }
2462
- function genCssVariables(theme) {
2478
+ function genCssVariables(theme, prefix) {
2463
2479
  const lightOverlay = theme.dark ? 2 : 1;
2464
2480
  const darkOverlay = theme.dark ? 1 : 2;
2465
2481
  const variables = [];
2466
2482
  for (const [key, value] of Object.entries(theme.colors)) {
2467
2483
  const rgb = parseColor(value);
2468
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2484
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2469
2485
  if (!key.startsWith('on-')) {
2470
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2486
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2471
2487
  }
2472
2488
  }
2473
2489
  for (const [key, value] of Object.entries(theme.variables)) {
2474
2490
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2475
2491
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2476
- variables.push(`--v-${key}: ${rgb ?? value}`);
2492
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2477
2493
  }
2478
2494
  return variables;
2479
2495
  }
@@ -2517,7 +2533,8 @@
2517
2533
  const scopeSelector = `:where(${scope})`;
2518
2534
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2519
2535
  }
2520
- function upsertStyles(styleEl, styles) {
2536
+ function upsertStyles(id, cspNonce, styles) {
2537
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2521
2538
  if (!styleEl) return;
2522
2539
  styleEl.innerHTML = styles;
2523
2540
  }
@@ -2537,8 +2554,17 @@
2537
2554
  // Composables
2538
2555
  function createTheme(options) {
2539
2556
  const parsedOptions = parseThemeOptions(options);
2540
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2557
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2541
2558
  const themes = vue.ref(parsedOptions.themes);
2559
+ const systemName = vue.shallowRef('light');
2560
+ const name = vue.computed({
2561
+ get() {
2562
+ return _name.value === 'system' ? systemName.value : _name.value;
2563
+ },
2564
+ set(val) {
2565
+ _name.value = val;
2566
+ }
2567
+ });
2542
2568
  const computedThemes = vue.computed(() => {
2543
2569
  const acc = {};
2544
2570
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2559,28 +2585,49 @@
2559
2585
  const current = vue.toRef(() => computedThemes.value[name.value]);
2560
2586
  const styles = vue.computed(() => {
2561
2587
  const lines = [];
2588
+ const important = parsedOptions.unimportant ? '' : ' !important';
2589
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2562
2590
  if (current.value?.dark) {
2563
2591
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2564
2592
  }
2565
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2593
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2566
2594
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2567
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2568
- }
2569
- const bgLines = [];
2570
- const fgLines = [];
2571
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2572
- for (const key of colors) {
2573
- if (key.startsWith('on-')) {
2574
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2575
- } else {
2576
- 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);
2577
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2578
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2595
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2596
+ }
2597
+ if (parsedOptions.utilities) {
2598
+ const bgLines = [];
2599
+ const fgLines = [];
2600
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2601
+ for (const key of colors) {
2602
+ if (key.startsWith('on-')) {
2603
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2604
+ } else {
2605
+ 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);
2606
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2607
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2608
+ }
2579
2609
  }
2610
+ lines.push(...bgLines, ...fgLines);
2580
2611
  }
2581
- lines.push(...bgLines, ...fgLines);
2582
2612
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2583
2613
  });
2614
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2615
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2616
+ if (SUPPORTS_MATCH_MEDIA) {
2617
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2618
+ function updateSystemName() {
2619
+ systemName.value = media.matches ? 'dark' : 'light';
2620
+ }
2621
+ updateSystemName();
2622
+ media.addEventListener('change', updateSystemName, {
2623
+ passive: true
2624
+ });
2625
+ if (vue.getCurrentScope()) {
2626
+ vue.onScopeDispose(() => {
2627
+ media.removeEventListener('change', updateSystemName);
2628
+ });
2629
+ }
2630
+ }
2584
2631
  function install(app) {
2585
2632
  if (parsedOptions.isDisabled) return;
2586
2633
  const head = app._context.provides.usehead;
@@ -2618,22 +2665,55 @@
2618
2665
  updateStyles();
2619
2666
  }
2620
2667
  function updateStyles() {
2621
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2668
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2622
2669
  }
2623
2670
  }
2624
2671
  }
2625
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2672
+ function change(themeName) {
2673
+ if (!themeNames.value.includes(themeName)) {
2674
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2675
+ return;
2676
+ }
2677
+ name.value = themeName;
2678
+ }
2679
+ function cycle() {
2680
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2681
+ const currentIndex = themeArray.indexOf(name.value);
2682
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2683
+ change(themeArray[nextIndex]);
2684
+ }
2685
+ function toggle() {
2686
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2687
+ cycle(themeArray);
2688
+ }
2689
+ const globalName = new Proxy(name, {
2690
+ get(target, prop) {
2691
+ return target[prop];
2692
+ },
2693
+ set(target, prop, val) {
2694
+ if (prop === 'value') {
2695
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2696
+ }
2697
+ // @ts-expect-error
2698
+ target[prop] = val;
2699
+ return true;
2700
+ }
2701
+ });
2626
2702
  return {
2627
2703
  install,
2704
+ change,
2705
+ cycle,
2706
+ toggle,
2628
2707
  isDisabled: parsedOptions.isDisabled,
2629
2708
  name,
2630
2709
  themes,
2631
2710
  current,
2632
2711
  computedThemes,
2712
+ prefix: parsedOptions.prefix,
2633
2713
  themeClasses,
2634
2714
  styles,
2635
2715
  global: {
2636
- name,
2716
+ name: globalName,
2637
2717
  current
2638
2718
  }
2639
2719
  };
@@ -2644,7 +2724,7 @@
2644
2724
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2645
2725
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2646
2726
  const current = vue.toRef(() => theme.themes.value[name.value]);
2647
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2727
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2648
2728
  const newTheme = {
2649
2729
  ...theme,
2650
2730
  name,
@@ -3748,7 +3828,10 @@
3748
3828
  default: 'default',
3749
3829
  validator: v => allowedDensities$1.includes(v)
3750
3830
  },
3751
- extended: Boolean,
3831
+ extended: {
3832
+ type: Boolean,
3833
+ default: null
3834
+ },
3752
3835
  extensionHeight: {
3753
3836
  type: [Number, String],
3754
3837
  default: 48
@@ -3796,7 +3879,7 @@
3796
3879
  const {
3797
3880
  rtlClasses
3798
3881
  } = useRtl();
3799
- const isExtended = vue.shallowRef(!!(props.extended || slots.extension?.()));
3882
+ const isExtended = vue.shallowRef(props.extended === null ? !!slots.extension?.() : props.extended);
3800
3883
  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));
3801
3884
  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);
3802
3885
  provideDefaults({
@@ -3808,7 +3891,7 @@
3808
3891
  const hasTitle = !!(props.title || slots.title);
3809
3892
  const hasImage = !!(slots.image || props.image);
3810
3893
  const extension = slots.extension?.();
3811
- isExtended.value = !!(props.extended || extension);
3894
+ isExtended.value = props.extended === null ? !!extension : props.extended;
3812
3895
  return vue.createVNode(props.tag, {
3813
3896
  "class": vue.normalizeClass(['v-toolbar', {
3814
3897
  'v-toolbar--absolute': props.absolute,
@@ -4191,9 +4274,15 @@
4191
4274
  };
4192
4275
  }
4193
4276
 
4277
+ // Types
4278
+
4194
4279
  const makeVBtnGroupProps = propsFactory({
4195
4280
  baseColor: String,
4196
4281
  divided: Boolean,
4282
+ direction: {
4283
+ type: String,
4284
+ default: 'horizontal'
4285
+ },
4197
4286
  ...makeBorderProps(),
4198
4287
  ...makeComponentProps(),
4199
4288
  ...makeDensityProps(),
@@ -4227,7 +4316,7 @@
4227
4316
  } = useRounded(props);
4228
4317
  provideDefaults({
4229
4318
  VBtn: {
4230
- height: 'auto',
4319
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4231
4320
  baseColor: vue.toRef(() => props.baseColor),
4232
4321
  color: vue.toRef(() => props.color),
4233
4322
  density: vue.toRef(() => props.density),
@@ -4237,7 +4326,7 @@
4237
4326
  });
4238
4327
  useRender(() => {
4239
4328
  return vue.createVNode(props.tag, {
4240
- "class": vue.normalizeClass(['v-btn-group', {
4329
+ "class": vue.normalizeClass(['v-btn-group', `v-btn-group--${props.direction}`, {
4241
4330
  'v-btn-group--divided': props.divided
4242
4331
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
4243
4332
  "style": vue.normalizeStyle(props.style)
@@ -4404,6 +4493,7 @@
4404
4493
  } else {
4405
4494
  const isSelected = selected.value.includes(id);
4406
4495
  if (props.mandatory && isSelected) return;
4496
+ if (!isSelected && !value) return;
4407
4497
  selected.value = value ?? !isSelected ? [id] : [];
4408
4498
  }
4409
4499
  }
@@ -4838,7 +4928,7 @@
4838
4928
  const observer = new IntersectionObserver(entries => {
4839
4929
  isIntersecting.value = !!entries.find(entry => entry.isIntersecting);
4840
4930
  }, options);
4841
- vue.onBeforeUnmount(() => {
4931
+ vue.onScopeDispose(() => {
4842
4932
  observer.disconnect();
4843
4933
  });
4844
4934
  vue.watch(intersectionRef, (newValue, oldValue) => {
@@ -5369,9 +5459,9 @@
5369
5459
 
5370
5460
  function useSelectLink(link, select) {
5371
5461
  vue.watch(() => link.isActive?.value, isActive => {
5372
- if (link.isLink.value && isActive && select) {
5462
+ if (link.isLink.value && isActive != null && select) {
5373
5463
  vue.nextTick(() => {
5374
- select(true);
5464
+ select(isActive);
5375
5465
  });
5376
5466
  }
5377
5467
  }, {
@@ -5569,8 +5659,8 @@
5569
5659
  window.clearTimeout(element._ripple.showTimer);
5570
5660
  }
5571
5661
  let keyboardRipple = false;
5572
- function keyboardRippleShow(e) {
5573
- if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
5662
+ function keyboardRippleShow(e, keys) {
5663
+ if (!keyboardRipple && keys.includes(e.keyCode)) {
5574
5664
  keyboardRipple = true;
5575
5665
  rippleShow(e);
5576
5666
  }
@@ -5598,9 +5688,12 @@
5598
5688
  el._ripple.enabled = enabled;
5599
5689
  el._ripple.centered = modifiers.center;
5600
5690
  el._ripple.circle = modifiers.circle;
5601
- if (isObject(value) && value.class) {
5602
- el._ripple.class = value.class;
5691
+ const bindingValue = isObject(value) ? value : {};
5692
+ if (bindingValue.class) {
5693
+ el._ripple.class = bindingValue.class;
5603
5694
  }
5695
+ const allowedKeys = bindingValue.keys ?? [keyCodes.enter, keyCodes.space];
5696
+ el._ripple.keyDownHandler = e => keyboardRippleShow(e, allowedKeys);
5604
5697
  if (enabled && !wasEnabled) {
5605
5698
  if (modifiers.stop) {
5606
5699
  el.addEventListener('touchstart', rippleStop, {
@@ -5622,7 +5715,7 @@
5622
5715
  el.addEventListener('mousedown', rippleShow);
5623
5716
  el.addEventListener('mouseup', rippleHide);
5624
5717
  el.addEventListener('mouseleave', rippleHide);
5625
- el.addEventListener('keydown', keyboardRippleShow);
5718
+ el.addEventListener('keydown', e => keyboardRippleShow(e, allowedKeys));
5626
5719
  el.addEventListener('keyup', keyboardRippleHide);
5627
5720
  el.addEventListener('blur', focusRippleHide);
5628
5721
 
@@ -5642,7 +5735,9 @@
5642
5735
  el.removeEventListener('touchcancel', rippleHide);
5643
5736
  el.removeEventListener('mouseup', rippleHide);
5644
5737
  el.removeEventListener('mouseleave', rippleHide);
5645
- el.removeEventListener('keydown', keyboardRippleShow);
5738
+ if (el._ripple?.keyDownHandler) {
5739
+ el.removeEventListener('keydown', el._ripple.keyDownHandler);
5740
+ }
5646
5741
  el.removeEventListener('keyup', keyboardRippleHide);
5647
5742
  el.removeEventListener('dragstart', rippleHide);
5648
5743
  el.removeEventListener('blur', focusRippleHide);
@@ -5651,8 +5746,8 @@
5651
5746
  updateRipple(el, binding, false);
5652
5747
  }
5653
5748
  function unmounted$4(el) {
5654
- delete el._ripple;
5655
5749
  removeListeners(el);
5750
+ delete el._ripple;
5656
5751
  }
5657
5752
  function updated$1(el, binding) {
5658
5753
  if (binding.value === binding.oldValue) {
@@ -5925,6 +6020,31 @@
5925
6020
  // Utilities
5926
6021
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5927
6022
 
6023
+ // Utilities
6024
+
6025
+ // Types
6026
+
6027
+ // Types
6028
+
6029
+ // Composables
6030
+ const makeIconSizeProps = propsFactory({
6031
+ iconSize: [Number, String],
6032
+ iconSizes: {
6033
+ type: Array,
6034
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6035
+ }
6036
+ }, 'iconSize');
6037
+ function useIconSizes(props, fallback) {
6038
+ const iconSize = vue.computed(() => {
6039
+ const iconSizeMap = new Map(props.iconSizes);
6040
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6041
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6042
+ });
6043
+ return {
6044
+ iconSize
6045
+ };
6046
+ }
6047
+
5928
6048
  // Types
5929
6049
 
5930
6050
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5964,6 +6084,7 @@
5964
6084
  ...makeDensityProps(),
5965
6085
  ...makeDimensionProps(),
5966
6086
  ...makeElevationProps(),
6087
+ ...makeIconSizeProps(),
5967
6088
  ...makeLocationProps(),
5968
6089
  ...makePositionProps(),
5969
6090
  ...makeRoundedProps(),
@@ -5991,6 +6112,9 @@
5991
6112
  if (!props.type) return props.icon;
5992
6113
  return props.icon ?? `$${props.type}`;
5993
6114
  });
6115
+ const {
6116
+ iconSize
6117
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5994
6118
  const {
5995
6119
  themeClasses
5996
6120
  } = provideTheme(props);
@@ -6038,6 +6162,11 @@
6038
6162
  const hasPrepend = !!(slots.prepend || icon.value);
6039
6163
  const hasTitle = !!(slots.title || props.title);
6040
6164
  const hasClose = !!(slots.close || props.closable);
6165
+ const iconProps = {
6166
+ density: props.density,
6167
+ icon: icon.value,
6168
+ size: iconSize.value
6169
+ };
6041
6170
  return isActive.value && vue.createVNode(props.tag, {
6042
6171
  "class": vue.normalizeClass(['v-alert', props.border && {
6043
6172
  'v-alert--border': !!props.border,
@@ -6055,19 +6184,14 @@
6055
6184
  }, null), hasPrepend && vue.createElementVNode("div", {
6056
6185
  "key": "prepend",
6057
6186
  "class": "v-alert__prepend"
6058
- }, [!slots.prepend ? vue.createVNode(VIcon, {
6059
- "key": "prepend-icon",
6060
- "density": props.density,
6061
- "icon": icon.value,
6062
- "size": props.prominent ? 44 : 28
6063
- }, null) : vue.createVNode(VDefaultsProvider, {
6187
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6188
+ "key": "prepend-icon"
6189
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6064
6190
  "key": "prepend-defaults",
6065
6191
  "disabled": !icon.value,
6066
6192
  "defaults": {
6067
6193
  VIcon: {
6068
- density: props.density,
6069
- icon: icon.value,
6070
- size: props.prominent ? 44 : 28
6194
+ ...iconProps
6071
6195
  }
6072
6196
  }
6073
6197
  }, slots.prepend)]), vue.createElementVNode("div", {
@@ -7592,6 +7716,7 @@
7592
7716
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7593
7717
  const makeVSlideGroupProps = propsFactory({
7594
7718
  centerActive: Boolean,
7719
+ contentClass: null,
7595
7720
  direction: {
7596
7721
  type: String,
7597
7722
  default: 'horizontal'
@@ -7904,7 +8029,7 @@
7904
8029
  })]), vue.createElementVNode("div", {
7905
8030
  "key": "container",
7906
8031
  "ref": containerRef,
7907
- "class": "v-slide-group__container",
8032
+ "class": vue.normalizeClass(['v-slide-group__container', props.contentClass]),
7908
8033
  "onScroll": onScroll
7909
8034
  }, [vue.createElementVNode("div", {
7910
8035
  "ref": contentRef,
@@ -8267,16 +8392,85 @@
8267
8392
  }
8268
8393
  });
8269
8394
 
8395
+ const makeVDividerProps = propsFactory({
8396
+ color: String,
8397
+ inset: Boolean,
8398
+ length: [Number, String],
8399
+ opacity: [Number, String],
8400
+ thickness: [Number, String],
8401
+ vertical: Boolean,
8402
+ ...makeComponentProps(),
8403
+ ...makeThemeProps()
8404
+ }, 'VDivider');
8405
+ const VDivider = genericComponent()({
8406
+ name: 'VDivider',
8407
+ props: makeVDividerProps(),
8408
+ setup(props, _ref) {
8409
+ let {
8410
+ attrs,
8411
+ slots
8412
+ } = _ref;
8413
+ const {
8414
+ themeClasses
8415
+ } = provideTheme(props);
8416
+ const {
8417
+ textColorClasses,
8418
+ textColorStyles
8419
+ } = useTextColor(() => props.color);
8420
+ const dividerStyles = vue.computed(() => {
8421
+ const styles = {};
8422
+ if (props.length) {
8423
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8424
+ }
8425
+ if (props.thickness) {
8426
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8427
+ }
8428
+ return styles;
8429
+ });
8430
+ useRender(() => {
8431
+ const divider = vue.createElementVNode("hr", {
8432
+ "class": vue.normalizeClass([{
8433
+ 'v-divider': true,
8434
+ 'v-divider--inset': props.inset,
8435
+ 'v-divider--vertical': props.vertical
8436
+ }, themeClasses.value, textColorClasses.value, props.class]),
8437
+ "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
8438
+ '--v-border-opacity': props.opacity
8439
+ }, props.style]),
8440
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8441
+ "role": `${attrs.role || 'separator'}`
8442
+ }, null);
8443
+ if (!slots.default) return divider;
8444
+ return vue.createElementVNode("div", {
8445
+ "class": vue.normalizeClass(['v-divider__wrapper', {
8446
+ 'v-divider__wrapper--vertical': props.vertical,
8447
+ 'v-divider__wrapper--inset': props.inset
8448
+ }])
8449
+ }, [divider, vue.createElementVNode("div", {
8450
+ "class": "v-divider__content"
8451
+ }, [slots.default()]), divider]);
8452
+ });
8453
+ return {};
8454
+ }
8455
+ });
8456
+
8270
8457
  // Utilities
8271
8458
 
8272
8459
  // List
8273
8460
  const ListKey = Symbol.for('vuetify:list');
8274
8461
  function createList() {
8462
+ let {
8463
+ filterable
8464
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
8465
+ filterable: false
8466
+ };
8275
8467
  const parent = vue.inject(ListKey, {
8468
+ filterable: false,
8276
8469
  hasPrepend: vue.shallowRef(false),
8277
8470
  updateHasPrepend: () => null
8278
8471
  });
8279
8472
  const data = {
8473
+ filterable: parent.filterable || filterable,
8280
8474
  hasPrepend: vue.shallowRef(false),
8281
8475
  updateHasPrepend: value => {
8282
8476
  if (value) data.hasPrepend.value = value;
@@ -8985,6 +9179,7 @@
8985
9179
  type: IconValue,
8986
9180
  default: '$expand'
8987
9181
  },
9182
+ rawId: [String, Number],
8988
9183
  prependIcon: IconValue,
8989
9184
  appendIcon: IconValue,
8990
9185
  fluid: Boolean,
@@ -9006,13 +9201,12 @@
9006
9201
  open,
9007
9202
  id: _id
9008
9203
  } = useNestedItem(() => props.value, true);
9009
- const id = vue.computed(() => `v-list-group--id-${String(_id.value)}`);
9204
+ const id = vue.computed(() => `v-list-group--id-${String(props.rawId ?? _id.value)}`);
9010
9205
  const list = useList();
9011
9206
  const {
9012
9207
  isBooted
9013
9208
  } = useSsrBoot();
9014
9209
  function onClick(e) {
9015
- e.stopPropagation();
9016
9210
  if (['INPUT', 'TEXTAREA'].includes(e.target?.tagName)) return;
9017
9211
  open(!isOpen.value, e);
9018
9212
  }
@@ -9228,6 +9422,9 @@
9228
9422
  roundedClasses
9229
9423
  } = useRounded(roundedProps);
9230
9424
  const lineClasses = vue.toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
9425
+ const rippleOptions = vue.toRef(() => props.ripple !== undefined && !!props.ripple && list?.filterable ? {
9426
+ keys: [keyCodes.enter]
9427
+ } : props.ripple);
9231
9428
  const slotProps = vue.computed(() => ({
9232
9429
  isActive: isActive.value,
9233
9430
  select,
@@ -9252,8 +9449,9 @@
9252
9449
  function onKeyDown(e) {
9253
9450
  const target = e.target;
9254
9451
  if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
9255
- if (e.key === 'Enter' || e.key === ' ') {
9452
+ if (e.key === 'Enter' || e.key === ' ' && !list?.filterable) {
9256
9453
  e.preventDefault();
9454
+ e.stopPropagation();
9257
9455
  e.target.dispatchEvent(new MouseEvent('click', e));
9258
9456
  }
9259
9457
  }
@@ -9363,7 +9561,7 @@
9363
9561
  }), vue.createElementVNode("div", {
9364
9562
  "class": "v-list-item__spacer"
9365
9563
  }, null)])]
9366
- }), [[Ripple, isClickable.value && props.ripple]]);
9564
+ }), [[Ripple, isClickable.value && rippleOptions.value]]);
9367
9565
  });
9368
9566
  return {
9369
9567
  activate,
@@ -9418,68 +9616,6 @@
9418
9616
  }
9419
9617
  });
9420
9618
 
9421
- const makeVDividerProps = propsFactory({
9422
- color: String,
9423
- inset: Boolean,
9424
- length: [Number, String],
9425
- opacity: [Number, String],
9426
- thickness: [Number, String],
9427
- vertical: Boolean,
9428
- ...makeComponentProps(),
9429
- ...makeThemeProps()
9430
- }, 'VDivider');
9431
- const VDivider = genericComponent()({
9432
- name: 'VDivider',
9433
- props: makeVDividerProps(),
9434
- setup(props, _ref) {
9435
- let {
9436
- attrs,
9437
- slots
9438
- } = _ref;
9439
- const {
9440
- themeClasses
9441
- } = provideTheme(props);
9442
- const {
9443
- textColorClasses,
9444
- textColorStyles
9445
- } = useTextColor(() => props.color);
9446
- const dividerStyles = vue.computed(() => {
9447
- const styles = {};
9448
- if (props.length) {
9449
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9450
- }
9451
- if (props.thickness) {
9452
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9453
- }
9454
- return styles;
9455
- });
9456
- useRender(() => {
9457
- const divider = vue.createElementVNode("hr", {
9458
- "class": vue.normalizeClass([{
9459
- 'v-divider': true,
9460
- 'v-divider--inset': props.inset,
9461
- 'v-divider--vertical': props.vertical
9462
- }, themeClasses.value, textColorClasses.value, props.class]),
9463
- "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
9464
- '--v-border-opacity': props.opacity
9465
- }, props.style]),
9466
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9467
- "role": `${attrs.role || 'separator'}`
9468
- }, null);
9469
- if (!slots.default) return divider;
9470
- return vue.createElementVNode("div", {
9471
- "class": vue.normalizeClass(['v-divider__wrapper', {
9472
- 'v-divider__wrapper--vertical': props.vertical,
9473
- 'v-divider__wrapper--inset': props.inset
9474
- }])
9475
- }, [divider, vue.createElementVNode("div", {
9476
- "class": "v-divider__content"
9477
- }, [slots.default()]), divider]);
9478
- });
9479
- return {};
9480
- }
9481
- });
9482
-
9483
9619
  // Types
9484
9620
 
9485
9621
  const makeVListChildrenProps = propsFactory({
@@ -9530,9 +9666,10 @@
9530
9666
  }) : undefined
9531
9667
  };
9532
9668
  const listGroupProps = VListGroup.filterProps(itemProps);
9533
- return children ? vue.createVNode(VListGroup, vue.mergeProps({
9534
- "value": itemProps?.value
9535
- }, listGroupProps), {
9669
+ return children ? vue.createVNode(VListGroup, vue.mergeProps(listGroupProps, {
9670
+ "value": props.returnObject ? item : itemProps?.value,
9671
+ "rawId": itemProps?.value
9672
+ }), {
9536
9673
  activator: _ref3 => {
9537
9674
  let {
9538
9675
  props: activatorProps
@@ -9748,6 +9885,7 @@
9748
9885
  activeClass: String,
9749
9886
  bgColor: String,
9750
9887
  disabled: Boolean,
9888
+ filterable: Boolean,
9751
9889
  expandIcon: IconValue,
9752
9890
  collapseIcon: IconValue,
9753
9891
  lines: {
@@ -9831,7 +9969,9 @@
9831
9969
  const activeColor = vue.toRef(() => props.activeColor);
9832
9970
  const baseColor = vue.toRef(() => props.baseColor);
9833
9971
  const color = vue.toRef(() => props.color);
9834
- createList();
9972
+ createList({
9973
+ filterable: props.filterable
9974
+ });
9835
9975
  provideDefaults({
9836
9976
  VListGroup: {
9837
9977
  activeColor,
@@ -11514,6 +11654,7 @@
11514
11654
  // disableKeys: Boolean,
11515
11655
  id: String,
11516
11656
  submenu: Boolean,
11657
+ disableInitialFocus: Boolean,
11517
11658
  ...omit(makeVOverlayProps({
11518
11659
  closeDelay: 250,
11519
11660
  closeOnContentClick: true,
@@ -11588,7 +11729,7 @@
11588
11729
  vue.watch(isActive, val => {
11589
11730
  if (val) {
11590
11731
  parent?.register();
11591
- if (IN_BROWSER) {
11732
+ if (IN_BROWSER && !props.disableInitialFocus) {
11592
11733
  document.addEventListener('focusin', onFocusIn, {
11593
11734
  once: true
11594
11735
  });
@@ -12068,6 +12209,16 @@
12068
12209
  }
12069
12210
  });
12070
12211
 
12212
+ function useAutofocus(props) {
12213
+ function onIntersect(isIntersecting, entries) {
12214
+ if (!props.autofocus || !isIntersecting) return;
12215
+ entries[0].target?.focus?.();
12216
+ }
12217
+ return {
12218
+ onIntersect
12219
+ };
12220
+ }
12221
+
12071
12222
  // Types
12072
12223
 
12073
12224
  const activeTypes = ['color', 'file', 'time', 'date', 'datetime-local', 'week', 'month'];
@@ -12114,6 +12265,9 @@
12114
12265
  focus,
12115
12266
  blur
12116
12267
  } = useFocus(props);
12268
+ const {
12269
+ onIntersect
12270
+ } = useAutofocus(props);
12117
12271
  const counterValue = vue.computed(() => {
12118
12272
  return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : (model.value ?? '').toString().length;
12119
12273
  });
@@ -12123,10 +12277,6 @@
12123
12277
  return props.counter;
12124
12278
  });
12125
12279
  const isPlainOrUnderlined = vue.computed(() => ['plain', 'underlined'].includes(props.variant));
12126
- function onIntersect(isIntersecting, entries) {
12127
- if (!props.autofocus || !isIntersecting) return;
12128
- entries[0].target?.focus?.();
12129
- }
12130
12280
  const vInputRef = vue.ref();
12131
12281
  const vFieldRef = vue.ref();
12132
12282
  const inputRef = vue.ref();
@@ -12416,7 +12566,12 @@
12416
12566
  }
12417
12567
  function calculateOffset(index) {
12418
12568
  index = clamp(index, 0, items.value.length - 1);
12419
- return offsets[index] || 0;
12569
+ const whole = Math.floor(index);
12570
+ const fraction = index % 1;
12571
+ const next = whole + 1;
12572
+ const wholeOffset = offsets[whole] || 0;
12573
+ const nextOffset = offsets[next] || wholeOffset;
12574
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12420
12575
  }
12421
12576
  function calculateIndex(scrollTop) {
12422
12577
  return binaryClosest(offsets, scrollTop);
@@ -12770,6 +12925,7 @@
12770
12925
  },
12771
12926
  openOnClear: Boolean,
12772
12927
  itemColor: String,
12928
+ noAutoScroll: Boolean,
12773
12929
  ...makeItemsProps({
12774
12930
  itemChildren: false
12775
12931
  })
@@ -12984,7 +13140,7 @@
12984
13140
  vue.watch(menu, () => {
12985
13141
  if (!props.hideSelected && menu.value && model.value.length) {
12986
13142
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
12987
- IN_BROWSER && window.requestAnimationFrame(() => {
13143
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
12988
13144
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
12989
13145
  });
12990
13146
  }
@@ -13077,6 +13233,22 @@
13077
13233
  key: item.value,
13078
13234
  onClick: () => select(item, null)
13079
13235
  });
13236
+ if (item.raw.type === 'divider') {
13237
+ return slots.divider?.({
13238
+ props: item.raw,
13239
+ index
13240
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13241
+ "key": `divider-${index}`
13242
+ }), null);
13243
+ }
13244
+ if (item.raw.type === 'subheader') {
13245
+ return slots.subheader?.({
13246
+ props: item.raw,
13247
+ index
13248
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13249
+ "key": `subheader-${index}`
13250
+ }), null);
13251
+ }
13080
13252
  return slots.item?.({
13081
13253
  item,
13082
13254
  index,
@@ -13237,6 +13409,9 @@
13237
13409
  let match = -1;
13238
13410
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13239
13411
  if (typeof item === 'object') {
13412
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13413
+ continue;
13414
+ }
13240
13415
  const filterKeys = keys || Object.keys(transformed);
13241
13416
  for (const key of filterKeys) {
13242
13417
  const value = getPropertyFromItem(transformed, key);
@@ -13439,7 +13614,7 @@
13439
13614
  menu.value = !menu.value;
13440
13615
  }
13441
13616
  function onListKeydown(e) {
13442
- if (e.key !== ' ' && checkPrintable(e)) {
13617
+ if (checkPrintable(e) || e.key === 'Backspace') {
13443
13618
  vTextFieldRef.value?.focus();
13444
13619
  }
13445
13620
  }
@@ -13644,6 +13819,7 @@
13644
13819
  }, props.menuProps), {
13645
13820
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
13646
13821
  "ref": listRef,
13822
+ "filterable": true,
13647
13823
  "selected": selectedValues.value,
13648
13824
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
13649
13825
  "onMousedown": e => e.preventDefault(),
@@ -13675,6 +13851,22 @@
13675
13851
  active: highlightFirst.value && index === 0 ? true : undefined,
13676
13852
  onClick: () => select(item, null)
13677
13853
  });
13854
+ if (item.raw.type === 'divider') {
13855
+ return slots.divider?.({
13856
+ props: item.raw,
13857
+ index
13858
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13859
+ "key": `divider-${index}`
13860
+ }), null);
13861
+ }
13862
+ if (item.raw.type === 'subheader') {
13863
+ return slots.subheader?.({
13864
+ props: item.raw,
13865
+ index
13866
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13867
+ "key": `subheader-${index}`
13868
+ }), null);
13869
+ }
13678
13870
  return slots.item?.({
13679
13871
  item,
13680
13872
  index,
@@ -13819,7 +14011,8 @@
13819
14011
  ...makeThemeProps(),
13820
14012
  ...makeTransitionProps({
13821
14013
  transition: 'scale-rotate-transition'
13822
- })
14014
+ }),
14015
+ ...makeDimensionProps()
13823
14016
  }, 'VBadge');
13824
14017
  const VBadge = genericComponent()({
13825
14018
  name: 'VBadge',
@@ -13849,6 +14042,9 @@
13849
14042
  const base = props.floating ? props.dot ? 2 : 4 : props.dot ? 8 : 12;
13850
14043
  return base + (['top', 'bottom'].includes(side) ? Number(props.offsetY ?? 0) : ['left', 'right'].includes(side) ? Number(props.offsetX ?? 0) : 0);
13851
14044
  });
14045
+ const {
14046
+ dimensionStyles
14047
+ } = useDimension(props);
13852
14048
  useRender(() => {
13853
14049
  const value = Number(props.content);
13854
14050
  const content = !props.max || isNaN(value) ? props.content : value <= Number(props.max) ? value : `${props.max}+`;
@@ -13870,7 +14066,7 @@
13870
14066
  }, {
13871
14067
  default: () => [vue.withDirectives(vue.createElementVNode("span", vue.mergeProps({
13872
14068
  "class": ['v-badge__badge', themeClasses.value, backgroundColorClasses.value, roundedClasses.value, textColorClasses.value],
13873
- "style": [backgroundColorStyles.value, textColorStyles.value, props.inline ? {} : locationStyles.value],
14069
+ "style": [backgroundColorStyles.value, textColorStyles.value, dimensionStyles.value, props.inline ? {} : locationStyles.value],
13874
14070
  "aria-atomic": "true",
13875
14071
  "aria-label": t(props.label, value),
13876
14072
  "aria-live": "polite",
@@ -17279,13 +17475,13 @@
17279
17475
  return null;
17280
17476
  }
17281
17477
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17282
- function getWeekdays(locale, firstDayOfWeek) {
17478
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17283
17479
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17284
17480
  return createRange(7).map(i => {
17285
17481
  const weekday = new Date(sundayJanuarySecond2000);
17286
17482
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17287
17483
  return new Intl.DateTimeFormat(locale, {
17288
- weekday: 'narrow'
17484
+ weekday: weekdayFormat ?? 'narrow'
17289
17485
  }).format(weekday);
17290
17486
  });
17291
17487
  }
@@ -17749,9 +17945,9 @@
17749
17945
  getDiff(date, comparing, unit) {
17750
17946
  return getDiff(date, comparing, unit);
17751
17947
  }
17752
- getWeekdays(firstDayOfWeek) {
17948
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17753
17949
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17754
- return getWeekdays(this.locale, firstDay);
17950
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17755
17951
  }
17756
17952
  getYear(date) {
17757
17953
  return getYear(date);
@@ -18106,6 +18302,7 @@
18106
18302
  _search.value = val ?? '';
18107
18303
  if (!props.multiple && !hasSelectionSlot.value) {
18108
18304
  model.value = [transformItem$3(props, val)];
18305
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18109
18306
  }
18110
18307
  if (val && props.multiple && props.delimiters?.length) {
18111
18308
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18186,7 +18383,7 @@
18186
18383
  menu.value = !menu.value;
18187
18384
  }
18188
18385
  function onListKeydown(e) {
18189
- if (e.key !== ' ' && checkPrintable(e)) {
18386
+ if (checkPrintable(e) || e.key === 'Backspace') {
18190
18387
  vTextFieldRef.value?.focus();
18191
18388
  }
18192
18389
  }
@@ -18391,6 +18588,7 @@
18391
18588
  }, props.menuProps), {
18392
18589
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18393
18590
  "ref": listRef,
18591
+ "filterable": true,
18394
18592
  "selected": selectedValues.value,
18395
18593
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18396
18594
  "onMousedown": e => e.preventDefault(),
@@ -18422,6 +18620,22 @@
18422
18620
  active: highlightFirst.value && index === 0 ? true : undefined,
18423
18621
  onClick: () => select(item, null)
18424
18622
  });
18623
+ if (item.raw.type === 'divider') {
18624
+ return slots.divider?.({
18625
+ props: item.raw,
18626
+ index
18627
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18628
+ "key": `divider-${index}`
18629
+ }), null);
18630
+ }
18631
+ if (item.raw.type === 'subheader') {
18632
+ return slots.subheader?.({
18633
+ props: item.raw,
18634
+ index
18635
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18636
+ "key": `subheader-${index}`
18637
+ }), null);
18638
+ }
18425
18639
  return slots.item?.({
18426
18640
  item,
18427
18641
  index,
@@ -20304,6 +20518,7 @@
20304
20518
  color: String,
20305
20519
  disableSort: Boolean,
20306
20520
  fixedHeader: Boolean,
20521
+ lastFixed: Boolean,
20307
20522
  multiSort: Boolean,
20308
20523
  sortAscIcon: {
20309
20524
  type: IconValue,
@@ -20350,10 +20565,11 @@
20350
20565
  loaderClasses
20351
20566
  } = useLoader(props);
20352
20567
  function getFixedStyles(column, y) {
20353
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20568
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20354
20569
  return {
20355
20570
  position: 'sticky',
20356
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20571
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20572
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20357
20573
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20358
20574
  };
20359
20575
  }
@@ -20869,11 +21085,18 @@
20869
21085
  }
20870
21086
  });
20871
21087
 
21088
+ // Types
21089
+
20872
21090
  const makeVTableProps = propsFactory({
20873
21091
  fixedHeader: Boolean,
20874
21092
  fixedFooter: Boolean,
20875
21093
  height: [Number, String],
20876
21094
  hover: Boolean,
21095
+ striped: {
21096
+ type: String,
21097
+ default: null,
21098
+ validator: v => ['even', 'odd'].includes(v)
21099
+ },
20877
21100
  ...makeComponentProps(),
20878
21101
  ...makeDensityProps(),
20879
21102
  ...makeTagProps(),
@@ -20900,7 +21123,9 @@
20900
21123
  'v-table--fixed-footer': props.fixedFooter,
20901
21124
  'v-table--has-top': !!slots.top,
20902
21125
  'v-table--has-bottom': !!slots.bottom,
20903
- 'v-table--hover': props.hover
21126
+ 'v-table--hover': props.hover,
21127
+ 'v-table--striped-even': props.striped === 'even',
21128
+ 'v-table--striped-odd': props.striped === 'odd'
20904
21129
  }, themeClasses.value, densityClasses.value, props.class]),
20905
21130
  "style": vue.normalizeStyle(props.style)
20906
21131
  }, {
@@ -22075,7 +22300,8 @@
22075
22300
  firstDayOfWeek: {
22076
22301
  type: [Number, String],
22077
22302
  default: undefined
22078
- }
22303
+ },
22304
+ weekdayFormat: String
22079
22305
  }, 'calendar');
22080
22306
  function useCalendar(props) {
22081
22307
  const adapter = useDate();
@@ -22316,7 +22542,7 @@
22316
22542
  "ref": daysRef,
22317
22543
  "key": daysInMonth.value[0].date?.toString(),
22318
22544
  "class": "v-date-picker-month__days"
22319
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => vue.createElementVNode("div", {
22545
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => vue.createElementVNode("div", {
22320
22546
  "class": vue.normalizeClass(['v-date-picker-month__day', 'v-date-picker-month__weekday'])
22321
22547
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22322
22548
  const slotProps = {
@@ -22825,7 +23051,9 @@
22825
23051
  "max": maxDate.value,
22826
23052
  "year": year.value,
22827
23053
  "allowedMonths": allowedMonths
22828
- }), null) : viewMode.value === 'year' ? vue.createVNode(VDatePickerYears, vue.mergeProps({
23054
+ }), {
23055
+ ...pick(slots, ['month'])
23056
+ }) : viewMode.value === 'year' ? vue.createVNode(VDatePickerYears, vue.mergeProps({
22829
23057
  "key": "date-picker-years"
22830
23058
  }, datePickerYearsProps, {
22831
23059
  "modelValue": year.value,
@@ -22833,7 +23061,9 @@
22833
23061
  "min": minDate.value,
22834
23062
  "max": maxDate.value,
22835
23063
  "allowedYears": allowedYears
22836
- }), null) : vue.createVNode(VDatePickerMonth, vue.mergeProps({
23064
+ }), {
23065
+ ...pick(slots, ['year'])
23066
+ }) : vue.createVNode(VDatePickerMonth, vue.mergeProps({
22837
23067
  "key": "date-picker-month"
22838
23068
  }, datePickerMonthProps, {
22839
23069
  "modelValue": model.value,
@@ -22844,7 +23074,9 @@
22844
23074
  "onUpdate:year": [$event => year.value = $event, onUpdateYear],
22845
23075
  "min": minDate.value,
22846
23076
  "max": maxDate.value
22847
- }), null)]
23077
+ }), {
23078
+ ...pick(slots, ['day'])
23079
+ })]
22848
23080
  })]),
22849
23081
  actions: slots.actions
22850
23082
  });
@@ -23935,6 +24167,9 @@
23935
24167
  startStatus.value = status;
23936
24168
  } else if (side === 'end') {
23937
24169
  endStatus.value = status;
24170
+ } else if (side === 'both') {
24171
+ startStatus.value = status;
24172
+ endStatus.value = status;
23938
24173
  }
23939
24174
  }
23940
24175
  function getStatus(side) {
@@ -24046,6 +24281,32 @@
24046
24281
  }, [renderSide('end', endStatus.value)])]
24047
24282
  });
24048
24283
  });
24284
+ function reset(side) {
24285
+ const effectiveSide = side ?? props.side;
24286
+ setStatus(effectiveSide, 'ok');
24287
+ vue.nextTick(() => {
24288
+ setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
24289
+ if (props.mode !== 'manual') {
24290
+ vue.nextTick(() => {
24291
+ window.requestAnimationFrame(() => {
24292
+ window.requestAnimationFrame(() => {
24293
+ window.requestAnimationFrame(() => {
24294
+ if (effectiveSide === 'both') {
24295
+ intersecting('start');
24296
+ intersecting('end');
24297
+ } else {
24298
+ intersecting(effectiveSide);
24299
+ }
24300
+ });
24301
+ });
24302
+ });
24303
+ });
24304
+ }
24305
+ });
24306
+ }
24307
+ return {
24308
+ reset
24309
+ };
24049
24310
  }
24050
24311
  });
24051
24312
 
@@ -24125,8 +24386,47 @@
24125
24386
  }
24126
24387
  });
24127
24388
 
24128
- // Styles
24129
- const VKbd = createSimpleFunctional('v-kbd', 'kbd');
24389
+ const makeVKbdProps = propsFactory({
24390
+ ...makeBorderProps(),
24391
+ ...makeComponentProps(),
24392
+ ...makeRoundedProps(),
24393
+ ...makeTagProps({
24394
+ tag: 'kbd'
24395
+ }),
24396
+ ...makeThemeProps(),
24397
+ ...makeElevationProps(),
24398
+ color: String
24399
+ }, 'VKbd');
24400
+ const VKbd = genericComponent()({
24401
+ name: 'VKbd',
24402
+ props: makeVKbdProps(),
24403
+ setup(props, _ref) {
24404
+ let {
24405
+ slots
24406
+ } = _ref;
24407
+ const {
24408
+ themeClasses
24409
+ } = provideTheme(props);
24410
+ const {
24411
+ borderClasses
24412
+ } = useBorder(props);
24413
+ const {
24414
+ roundedClasses
24415
+ } = useRounded(props);
24416
+ const {
24417
+ backgroundColorClasses,
24418
+ backgroundColorStyles
24419
+ } = useBackgroundColor(() => props.color);
24420
+ const {
24421
+ elevationClasses
24422
+ } = useElevation(props);
24423
+ useRender(() => vue.createVNode(props.tag, {
24424
+ "class": vue.normalizeClass(['v-kbd', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
24425
+ "style": vue.normalizeStyle([backgroundColorStyles.value, props.style])
24426
+ }, slots));
24427
+ return {};
24428
+ }
24429
+ });
24130
24430
 
24131
24431
  const makeVLayoutProps = propsFactory({
24132
24432
  ...makeComponentProps(),
@@ -24964,6 +25264,14 @@
24964
25264
  type: Number,
24965
25265
  default: 0
24966
25266
  },
25267
+ minFractionDigits: {
25268
+ type: Number,
25269
+ default: null
25270
+ },
25271
+ decimalSeparator: {
25272
+ type: String,
25273
+ validator: v => !v || v.length === 1
25274
+ },
24967
25275
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24968
25276
  }, 'VNumberInput');
24969
25277
  const VNumberInput = genericComponent()({
@@ -24989,11 +25297,24 @@
24989
25297
  const form = useForm(props);
24990
25298
  const controlsDisabled = vue.computed(() => form.isDisabled.value || form.isReadonly.value);
24991
25299
  const isFocused = vue.shallowRef(props.focused);
25300
+ const {
25301
+ decimalSeparator: decimalSeparatorFromLocale
25302
+ } = useLocale();
25303
+ const decimalSeparator = vue.computed(() => props.decimalSeparator?.[0] || decimalSeparatorFromLocale.value);
24992
25304
  function correctPrecision(val) {
24993
25305
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
25306
+ let trim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
24994
25307
  const fixed = precision == null ? String(val) : val.toFixed(precision);
24995
- return isFocused.value ? Number(fixed).toString() // trim zeros
24996
- : fixed;
25308
+ if (isFocused.value && trim) {
25309
+ return Number(fixed).toString() // trim zeros
25310
+ .replace('.', decimalSeparator.value);
25311
+ }
25312
+ if (props.minFractionDigits === null || precision !== null && precision < props.minFractionDigits) {
25313
+ return fixed.replace('.', decimalSeparator.value);
25314
+ }
25315
+ let [baseDigits, fractionDigits] = fixed.split('.');
25316
+ fractionDigits = (fractionDigits ?? '').padEnd(props.minFractionDigits, '0').replace(new RegExp(`(?<=\\d{${props.minFractionDigits}})0`, 'g'), '');
25317
+ return [baseDigits, fractionDigits].filter(Boolean).join(decimalSeparator.value);
24997
25318
  }
24998
25319
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24999
25320
  const _inputText = vue.shallowRef(null);
@@ -25010,8 +25331,11 @@
25010
25331
  if (val === null || val === '') {
25011
25332
  model.value = null;
25012
25333
  _inputText.value = null;
25013
- } else if (!isNaN(Number(val)) && Number(val) <= props.max && Number(val) >= props.min) {
25014
- model.value = Number(val);
25334
+ return;
25335
+ }
25336
+ const parsedValue = Number(val.replace(decimalSeparator.value, '.'));
25337
+ if (!isNaN(parsedValue) && parsedValue <= props.max && parsedValue >= props.min) {
25338
+ model.value = parsedValue;
25015
25339
  _inputText.value = val;
25016
25340
  }
25017
25341
  }
@@ -25048,6 +25372,7 @@
25048
25372
  }
25049
25373
  };
25050
25374
  vue.watch(() => props.precision, () => formatInputValue());
25375
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
25051
25376
  vue.onMounted(() => {
25052
25377
  clampModel();
25053
25378
  });
@@ -25081,24 +25406,24 @@
25081
25406
  selectionEnd
25082
25407
  } = inputElement ?? {};
25083
25408
  const potentialNewInputVal = existingTxt ? existingTxt.slice(0, selectionStart) + e.data + existingTxt.slice(selectionEnd) : e.data;
25084
- const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision);
25409
+ const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision, decimalSeparator.value);
25085
25410
 
25086
- // Only numbers, "-", "." are allowed
25087
- // AND "-", "." are allowed only once
25088
- // AND "-" is only allowed at the start
25089
- if (!/^-?(\d+(\.\d*)?|(\.\d+)|\d*|\.)$/.test(potentialNewInputVal)) {
25411
+ // Allow only numbers, "-" and {decimal separator}
25412
+ // Allow "-" and {decimal separator} only once
25413
+ // Allow "-" only at the start
25414
+ if (!new RegExp(`^-?\\d*${escapeForRegex(decimalSeparator.value)}?\\d*$`).test(potentialNewInputVal)) {
25090
25415
  e.preventDefault();
25091
25416
  inputElement.value = potentialNewNumber;
25092
25417
  }
25093
25418
  if (props.precision == null) return;
25094
25419
 
25095
25420
  // Ignore decimal digits above precision limit
25096
- if (potentialNewInputVal.split('.')[1]?.length > props.precision) {
25421
+ if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {
25097
25422
  e.preventDefault();
25098
25423
  inputElement.value = potentialNewNumber;
25099
25424
  }
25100
25425
  // Ignore decimal separator when precision = 0
25101
- if (props.precision === 0 && potentialNewInputVal.includes('.')) {
25426
+ if (props.precision === 0 && potentialNewInputVal.includes(decimalSeparator.value)) {
25102
25427
  e.preventDefault();
25103
25428
  inputElement.value = potentialNewNumber;
25104
25429
  }
@@ -25150,19 +25475,16 @@
25150
25475
  if (controlsDisabled.value) return;
25151
25476
  if (!vTextFieldRef.value) return;
25152
25477
  const actualText = vTextFieldRef.value.value;
25153
- if (actualText && !isNaN(Number(actualText))) {
25154
- inputText.value = correctPrecision(clamp(Number(actualText), props.min, props.max));
25478
+ const parsedValue = Number(actualText.replace(decimalSeparator.value, '.'));
25479
+ if (actualText && !isNaN(parsedValue)) {
25480
+ inputText.value = correctPrecision(clamp(parsedValue, props.min, props.max));
25155
25481
  } else {
25156
25482
  inputText.value = null;
25157
25483
  }
25158
25484
  }
25159
25485
  function formatInputValue() {
25160
25486
  if (controlsDisabled.value) return;
25161
- if (model.value === null || isNaN(model.value)) {
25162
- inputText.value = null;
25163
- return;
25164
- }
25165
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25487
+ inputText.value = model.value !== null && !isNaN(model.value) ? correctPrecision(model.value, props.precision, false) : null;
25166
25488
  }
25167
25489
  function trimDecimalZeros() {
25168
25490
  if (controlsDisabled.value) return;
@@ -25170,7 +25492,7 @@
25170
25492
  inputText.value = null;
25171
25493
  return;
25172
25494
  }
25173
- inputText.value = model.value.toString();
25495
+ inputText.value = model.value.toString().replace('.', decimalSeparator.value);
25174
25496
  }
25175
25497
  function onFocus() {
25176
25498
  trimDecimalZeros();
@@ -25372,6 +25694,21 @@
25372
25694
  const contentRef = vue.ref();
25373
25695
  const inputRef = vue.ref([]);
25374
25696
  const current = vue.computed(() => inputRef.value[focusIndex.value]);
25697
+ const intersectScope = vue.effectScope();
25698
+ intersectScope.run(() => {
25699
+ const {
25700
+ intersectionRef,
25701
+ isIntersecting
25702
+ } = useIntersectionObserver();
25703
+ vue.watch(isIntersecting, v => {
25704
+ if (!v) return;
25705
+ intersectionRef.value?.focus();
25706
+ intersectScope.stop();
25707
+ });
25708
+ vue.watchEffect(() => {
25709
+ intersectionRef.value = inputRef.value[0];
25710
+ });
25711
+ });
25375
25712
  function onInput() {
25376
25713
  // The maxlength attribute doesn't work for the number type input, so the text type is used.
25377
25714
  // The following logic simulates the behavior of a number input.
@@ -25422,9 +25759,10 @@
25422
25759
  e.preventDefault();
25423
25760
  e.stopPropagation();
25424
25761
  const clipboardText = e?.clipboardData?.getData('Text').trim().slice(0, length.value) ?? '';
25762
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25425
25763
  if (isValidNumber(clipboardText)) return;
25426
25764
  model.value = clipboardText.split('');
25427
- inputRef.value?.[index].blur();
25765
+ inputRef.value?.[finalIndex].focus();
25428
25766
  }
25429
25767
  function reset() {
25430
25768
  model.value = [];
@@ -28118,6 +28456,9 @@
28118
28456
  focus,
28119
28457
  blur
28120
28458
  } = useFocus(props);
28459
+ const {
28460
+ onIntersect
28461
+ } = useAutofocus(props);
28121
28462
  const counterValue = vue.computed(() => {
28122
28463
  return typeof props.counterValue === 'function' ? props.counterValue(model.value) : (model.value || '').toString().length;
28123
28464
  });
@@ -28126,10 +28467,6 @@
28126
28467
  if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
28127
28468
  return props.counter;
28128
28469
  });
28129
- function onIntersect(isIntersecting, entries) {
28130
- if (!props.autofocus || !isIntersecting) return;
28131
- entries[0].target?.focus?.();
28132
- }
28133
28470
  const vInputRef = vue.ref();
28134
28471
  const vFieldRef = vue.ref();
28135
28472
  const controlHeight = vue.shallowRef('');
@@ -30125,11 +30462,6 @@
30125
30462
  hideOverlay: Boolean,
30126
30463
  icon: [String, Function, Object],
30127
30464
  iconColor: String,
30128
- iconSize: [Number, String],
30129
- iconSizes: {
30130
- type: Array,
30131
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
30132
- },
30133
30465
  loading: Boolean,
30134
30466
  opacity: [Number, String],
30135
30467
  readonly: Boolean,
@@ -30149,6 +30481,7 @@
30149
30481
  ...makeBorderProps(),
30150
30482
  ...makeComponentProps(),
30151
30483
  ...makeElevationProps(),
30484
+ ...makeIconSizeProps(),
30152
30485
  ...makeRoundedProps(),
30153
30486
  ...makeTagProps({
30154
30487
  tag: 'button'
@@ -30203,7 +30536,6 @@
30203
30536
  })()
30204
30537
  }));
30205
30538
  const btnSizeMap = new Map(props.sizes);
30206
- const iconSizeMap = new Map(props.iconSizes);
30207
30539
  function onClick() {
30208
30540
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
30209
30541
  isActive.value = !isActive.value;
@@ -30215,12 +30547,12 @@
30215
30547
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
30216
30548
  const btnHeight = props.height ?? btnSize;
30217
30549
  const btnWidth = props.width ?? btnSize;
30218
- const _iconSize = props.iconSize;
30219
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
30220
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30550
+ const {
30551
+ iconSize
30552
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
30221
30553
  const iconProps = {
30222
30554
  icon,
30223
- size: iconSize,
30555
+ size: iconSize.value,
30224
30556
  iconColor: props.iconColor,
30225
30557
  opacity: props.opacity
30226
30558
  };
@@ -30263,7 +30595,7 @@
30263
30595
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30264
30596
  "indeterminate": "disable-shrink",
30265
30597
  "width": "2",
30266
- "size": iconSize
30598
+ "size": iconSize.value
30267
30599
  }, null)])]
30268
30600
  });
30269
30601
  });
@@ -30271,6 +30603,251 @@
30271
30603
  }
30272
30604
  });
30273
30605
 
30606
+ // Utilities
30607
+
30608
+ // Types
30609
+
30610
+ const makeMaskProps = propsFactory({
30611
+ mask: [String, Object],
30612
+ returnMaskedValue: Boolean
30613
+ }, 'mask');
30614
+ const defaultDelimiters = /[-!$%^&*()_+|~=`{}[\]:";'<>?,./\\ ]/;
30615
+ const presets = {
30616
+ 'credit-card': '#### - #### - #### - ####',
30617
+ date: '##/##/####',
30618
+ 'date-time': '##/##/#### ##:##',
30619
+ 'iso-date': '####-##-##',
30620
+ 'iso-date-time': '####-##-## ##:##',
30621
+ phone: '(###) ### - ####',
30622
+ social: '###-##-####',
30623
+ time: '##:##',
30624
+ 'time-with-seconds': '##:##:##'
30625
+ };
30626
+ function isMaskDelimiter(char) {
30627
+ return char ? defaultDelimiters.test(char) : false;
30628
+ }
30629
+ const defaultTokens = {
30630
+ '#': {
30631
+ pattern: /[0-9]/
30632
+ },
30633
+ A: {
30634
+ pattern: /[A-Z]/i,
30635
+ convert: v => v.toUpperCase()
30636
+ },
30637
+ a: {
30638
+ pattern: /[a-z]/i,
30639
+ convert: v => v.toLowerCase()
30640
+ },
30641
+ N: {
30642
+ pattern: /[0-9A-Z]/i,
30643
+ convert: v => v.toUpperCase()
30644
+ },
30645
+ n: {
30646
+ pattern: /[0-9a-z]/i,
30647
+ convert: v => v.toLowerCase()
30648
+ },
30649
+ X: {
30650
+ pattern: defaultDelimiters
30651
+ }
30652
+ };
30653
+ function useMask(props, inputRef) {
30654
+ const mask = vue.computed(() => {
30655
+ if (typeof props.mask === 'string') {
30656
+ if (props.mask in presets) return presets[props.mask];
30657
+ return props.mask;
30658
+ }
30659
+ return props.mask?.mask ?? '';
30660
+ });
30661
+ const tokens = vue.computed(() => {
30662
+ return {
30663
+ ...defaultTokens,
30664
+ ...(isObject(props.mask) ? props.mask.tokens : null)
30665
+ };
30666
+ });
30667
+ const selection = vue.shallowRef(0);
30668
+ const lazySelection = vue.shallowRef(0);
30669
+ function isMask(char) {
30670
+ return char in tokens.value;
30671
+ }
30672
+ function maskValidates(mask, char) {
30673
+ if (char == null || !isMask(mask)) return false;
30674
+ const item = tokens.value[mask];
30675
+ if (item.pattern) return item.pattern.test(char);
30676
+ return item.test(char);
30677
+ }
30678
+ function convert(mask, char) {
30679
+ const item = tokens.value[mask];
30680
+ return item.convert ? item.convert(char) : char;
30681
+ }
30682
+ function maskText(text) {
30683
+ const trimmedText = text?.trim().replace(/\s+/g, ' ');
30684
+ if (trimmedText == null) return '';
30685
+ if (!mask.value.length || !trimmedText.length) return trimmedText;
30686
+ let textIndex = 0;
30687
+ let maskIndex = 0;
30688
+ let newText = '';
30689
+ while (maskIndex < mask.value.length) {
30690
+ const mchar = mask.value[maskIndex];
30691
+ const tchar = trimmedText[textIndex];
30692
+
30693
+ // Escaped character in mask, the next mask character is inserted
30694
+ if (mchar === '\\') {
30695
+ newText += mask.value[maskIndex + 1];
30696
+ maskIndex += 2;
30697
+ continue;
30698
+ }
30699
+ if (!isMask(mchar)) {
30700
+ newText += mchar;
30701
+ if (tchar === mchar) {
30702
+ textIndex++;
30703
+ }
30704
+ } else if (maskValidates(mchar, tchar)) {
30705
+ newText += convert(mchar, tchar);
30706
+ textIndex++;
30707
+ } else {
30708
+ break;
30709
+ }
30710
+ maskIndex++;
30711
+ }
30712
+ return newText;
30713
+ }
30714
+ function unmaskText(text) {
30715
+ if (text == null) return null;
30716
+ if (!mask.value.length || !text.length) return text;
30717
+ let textIndex = 0;
30718
+ let maskIndex = 0;
30719
+ let newText = '';
30720
+ while (true) {
30721
+ const mchar = mask.value[maskIndex];
30722
+ const tchar = text[textIndex];
30723
+ if (tchar == null) break;
30724
+ if (mchar == null) {
30725
+ newText += tchar;
30726
+ textIndex++;
30727
+ continue;
30728
+ }
30729
+
30730
+ // Escaped character in mask, skip the next input character
30731
+ if (mchar === '\\') {
30732
+ if (tchar === mask.value[maskIndex + 1]) {
30733
+ textIndex++;
30734
+ }
30735
+ maskIndex += 2;
30736
+ continue;
30737
+ }
30738
+ if (maskValidates(mchar, tchar)) {
30739
+ // masked char
30740
+ newText += tchar;
30741
+ textIndex++;
30742
+ maskIndex++;
30743
+ continue;
30744
+ } else if (mchar !== tchar) {
30745
+ // input doesn't match mask, skip forward until it does
30746
+ while (true) {
30747
+ const mchar = mask.value[maskIndex++];
30748
+ if (mchar == null || maskValidates(mchar, tchar)) break;
30749
+ }
30750
+ continue;
30751
+ }
30752
+ textIndex++;
30753
+ maskIndex++;
30754
+ }
30755
+ return newText;
30756
+ }
30757
+ function setCaretPosition(newSelection) {
30758
+ selection.value = newSelection;
30759
+ inputRef.value && inputRef.value.setSelectionRange(selection.value, selection.value);
30760
+ }
30761
+ function resetSelections() {
30762
+ if (!inputRef.value?.selectionEnd) return;
30763
+ selection.value = inputRef.value.selectionEnd;
30764
+ lazySelection.value = 0;
30765
+ for (let index = 0; index < selection.value; index++) {
30766
+ isMaskDelimiter(inputRef.value.value[index]) || lazySelection.value++;
30767
+ }
30768
+ }
30769
+ function updateRange() {
30770
+ if (!inputRef.value) return;
30771
+ resetSelections();
30772
+ let selection = 0;
30773
+ const newValue = inputRef.value.value;
30774
+ if (newValue) {
30775
+ for (let index = 0; index < newValue.length; index++) {
30776
+ if (lazySelection.value <= 0) break;
30777
+ isMaskDelimiter(newValue[index]) || lazySelection.value--;
30778
+ selection++;
30779
+ }
30780
+ }
30781
+ setCaretPosition(selection);
30782
+ }
30783
+ return {
30784
+ updateRange,
30785
+ maskText,
30786
+ unmaskText
30787
+ };
30788
+ }
30789
+
30790
+ // Types
30791
+
30792
+ const makeVMaskInputProps = propsFactory({
30793
+ ...makeVTextFieldProps(),
30794
+ ...makeMaskProps()
30795
+ }, 'VMaskInput');
30796
+ const VMaskInput = genericComponent()({
30797
+ name: 'VMaskInput',
30798
+ props: makeVMaskInputProps(),
30799
+ emits: {
30800
+ 'update:modelValue': val => true
30801
+ },
30802
+ setup(props, _ref) {
30803
+ let {
30804
+ slots,
30805
+ emit
30806
+ } = _ref;
30807
+ const vTextFieldRef = vue.ref();
30808
+ const {
30809
+ maskText,
30810
+ updateRange,
30811
+ unmaskText
30812
+ } = useMask(props, vTextFieldRef);
30813
+ const returnMaskedValue = vue.computed(() => props.mask && props.returnMaskedValue);
30814
+ const model = useProxiedModel(props, 'modelValue', undefined,
30815
+ // Always display masked value in input when mask is applied
30816
+ val => props.mask ? maskText(unmaskText(val)) : val, val => {
30817
+ if (props.mask) {
30818
+ const valueBeforeChange = unmaskText(model.value);
30819
+ // E.g. mask is #-# and the input value is '2-23'
30820
+ // model-value should be enforced to '2-2'
30821
+ const enforcedMaskedValue = maskText(unmaskText(val));
30822
+ const newUnmaskedValue = unmaskText(enforcedMaskedValue);
30823
+ if (newUnmaskedValue === valueBeforeChange) {
30824
+ vTextFieldRef.value.value = enforcedMaskedValue;
30825
+ }
30826
+ val = newUnmaskedValue;
30827
+ updateRange();
30828
+ return returnMaskedValue.value ? maskText(val) : val;
30829
+ }
30830
+ return val;
30831
+ });
30832
+ vue.onBeforeMount(() => {
30833
+ if (props.returnMaskedValue) {
30834
+ emit('update:modelValue', model.value);
30835
+ }
30836
+ });
30837
+ useRender(() => {
30838
+ const textFieldProps = VTextField.filterProps(props);
30839
+ return vue.createVNode(VTextField, vue.mergeProps(textFieldProps, {
30840
+ "modelValue": model.value,
30841
+ "onUpdate:modelValue": $event => model.value = $event,
30842
+ "ref": vTextFieldRef
30843
+ }), {
30844
+ ...slots
30845
+ });
30846
+ });
30847
+ return forwardRefs({}, vTextFieldRef);
30848
+ }
30849
+ });
30850
+
30274
30851
  // Types
30275
30852
 
30276
30853
  const makeVStepperVerticalActionsProps = propsFactory({
@@ -31342,6 +31919,7 @@
31342
31919
  }
31343
31920
  function onClickAction(e) {
31344
31921
  e.preventDefault();
31922
+ e.stopPropagation();
31345
31923
  emit('toggleExpand', e);
31346
31924
  }
31347
31925
  useRender(() => {
@@ -31412,6 +31990,11 @@
31412
31990
  selectable: Boolean,
31413
31991
  selectedColor: String,
31414
31992
  selectStrategy: [String, Function, Object],
31993
+ index: Number,
31994
+ path: {
31995
+ type: Array,
31996
+ default: () => []
31997
+ },
31415
31998
  ...makeDensityProps()
31416
31999
  }, 'VTreeviewChildren');
31417
32000
  const VTreeviewChildren = genericComponent()({
@@ -31439,12 +32022,19 @@
31439
32022
  select(!isSelected);
31440
32023
  }
31441
32024
  }
31442
- return () => slots.default?.() ?? props.items?.map(item => {
32025
+ return () => slots.default?.() ?? props.items?.map((item, index) => {
31443
32026
  const {
31444
32027
  children,
31445
32028
  props: itemProps
31446
32029
  } = item;
31447
32030
  const loading = isLoading.has(item.value);
32031
+ const treeItemProps = {
32032
+ index,
32033
+ depth: props.path?.length ?? 0,
32034
+ isFirst: index === 0,
32035
+ isLast: props.items ? props.items.length - 1 === index : false,
32036
+ path: [...props.path, index]
32037
+ };
31448
32038
  const slotsWithItem = {
31449
32039
  prepend: slotProps => vue.createElementVNode(vue.Fragment, null, [props.selectable && (!children || children && !['leaf', 'single-leaf'].includes(props.selectStrategy)) && vue.createElementVNode("div", null, [vue.createVNode(VCheckboxBtn, {
31450
32040
  "key": item.value,
@@ -31465,11 +32055,13 @@
31465
32055
  }
31466
32056
  }, null)]), slots.prepend?.({
31467
32057
  ...slotProps,
32058
+ ...treeItemProps,
31468
32059
  item: item.raw,
31469
32060
  internalItem: item
31470
32061
  })]),
31471
32062
  append: slots.append ? slotProps => slots.append?.({
31472
32063
  ...slotProps,
32064
+ ...treeItemProps,
31473
32065
  item: item.raw,
31474
32066
  internalItem: item
31475
32067
  }) : undefined,
@@ -31485,9 +32077,13 @@
31485
32077
  }) : undefined
31486
32078
  };
31487
32079
  const treeviewGroupProps = VTreeviewGroup.filterProps(itemProps);
31488
- const treeviewChildrenProps = VTreeviewChildren.filterProps(props);
32080
+ const treeviewChildrenProps = VTreeviewChildren.filterProps({
32081
+ ...props,
32082
+ ...treeItemProps
32083
+ });
31489
32084
  return children ? vue.createVNode(VTreeviewGroup, vue.mergeProps(treeviewGroupProps, {
31490
- "value": props.returnObject ? item.raw : treeviewGroupProps?.value
32085
+ "value": props.returnObject ? item.raw : treeviewGroupProps?.value,
32086
+ "rawId": treeviewGroupProps?.value
31491
32087
  }), {
31492
32088
  activator: _ref2 => {
31493
32089
  let {
@@ -31535,7 +32131,7 @@
31535
32131
  ...makeFilterProps({
31536
32132
  filterKeys: ['title']
31537
32133
  }),
31538
- ...makeVTreeviewChildrenProps(),
32134
+ ...omit(makeVTreeviewChildrenProps(), ['index', 'path']),
31539
32135
  ...omit(makeVListProps({
31540
32136
  collapseIcon: '$treeviewCollapse',
31541
32137
  expandIcon: '$treeviewExpand',
@@ -31778,6 +32374,7 @@
31778
32374
  VListSubheader: VListSubheader,
31779
32375
  VLocaleProvider: VLocaleProvider,
31780
32376
  VMain: VMain,
32377
+ VMaskInput: VMaskInput,
31781
32378
  VMenu: VMenu,
31782
32379
  VMessages: VMessages,
31783
32380
  VNavigationDrawer: VNavigationDrawer,
@@ -32175,7 +32772,7 @@
32175
32772
  };
32176
32773
  });
32177
32774
  }
32178
- const version$1 = "3.8.9-master.2025-06-14";
32775
+ const version$1 = "3.8.10-dev.2025-06-18";
32179
32776
  createVuetify$1.version = version$1;
32180
32777
 
32181
32778
  // Vue's inject() can only be used in setup
@@ -32473,7 +33070,7 @@
32473
33070
 
32474
33071
  /* eslint-disable local-rules/sort-imports */
32475
33072
 
32476
- const version = "3.8.9-master.2025-06-14";
33073
+ const version = "3.8.10-dev.2025-06-18";
32477
33074
 
32478
33075
  /* eslint-disable local-rules/sort-imports */
32479
33076