@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,10 +1,10 @@
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
  */
6
6
 
7
- import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, camelize, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, createElementVNode, normalizeStyle, normalizeClass, createVNode, TransitionGroup, Transition, mergeProps, toRefs, toValue, isRef, onBeforeMount, nextTick, withDirectives, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, normalizeProps, guardReactiveProps, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
7
+ import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, camelize, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, createElementVNode, normalizeStyle, normalizeClass, createVNode, TransitionGroup, Transition, mergeProps, toRefs, toValue, isRef, onBeforeMount, nextTick, withDirectives, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, normalizeProps, guardReactiveProps, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
8
8
 
9
9
  // Types
10
10
  // eslint-disable-line vue/prefer-import-from-vue
@@ -81,6 +81,7 @@ const IN_BROWSER = typeof window !== 'undefined';
81
81
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
82
82
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
83
83
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
84
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
84
85
 
85
86
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
86
87
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -587,18 +588,23 @@ function checkPrintable(e) {
587
588
  function isPrimitive(value) {
588
589
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint';
589
590
  }
590
- function extractNumber(text, decimalDigitsLimit) {
591
- const cleanText = text.split('').filter(x => /[\d\-.]/.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
591
+ function escapeForRegex(sign) {
592
+ return '\\^$*+?.()|{}[]'.includes(sign) ? `\\${sign}` : sign;
593
+ }
594
+ function extractNumber(text, decimalDigitsLimit, decimalSeparator) {
595
+ const onlyValidCharacters = new RegExp(`[\\d\\-${escapeForRegex(decimalSeparator)}]`);
596
+ const cleanText = text.split('').filter(x => onlyValidCharacters.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
592
597
  // sign allowed at the start
593
- x === '.' && i === all.indexOf('.') ||
598
+ x === decimalSeparator && i === all.indexOf(x) ||
594
599
  // decimal separator allowed only once
595
600
  /\d/.test(x)).join('');
596
601
  if (decimalDigitsLimit === 0) {
597
- return cleanText.split('.')[0];
602
+ return cleanText.split(decimalSeparator)[0];
598
603
  }
599
- if (decimalDigitsLimit !== null && /\.\d/.test(cleanText)) {
600
- const parts = cleanText.split('.');
601
- return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join('.');
604
+ const decimalPart = new RegExp(`${escapeForRegex(decimalSeparator)}\\d`);
605
+ if (decimalDigitsLimit !== null && decimalPart.test(cleanText)) {
606
+ const parts = cleanText.split(decimalSeparator);
607
+ return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join(decimalSeparator);
602
608
  }
603
609
  return cleanText;
604
610
  }
@@ -940,7 +946,7 @@ function APCAcontrast(text, background) {
940
946
  // WoB should always return negative value.
941
947
 
942
948
  const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
943
- outputContrast = SAPC > -1e-3 ? 0.0 : SAPC > -0.078 ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
949
+ outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
944
950
  }
945
951
  return outputContrast * 100;
946
952
  }
@@ -2181,6 +2187,10 @@ function createNumberFunction(current, fallback) {
2181
2187
  return numberFormat.format(value);
2182
2188
  };
2183
2189
  }
2190
+ function inferDecimalSeparator(current, fallback) {
2191
+ const format = createNumberFunction(current, fallback);
2192
+ return format(0.1).includes(',') ? ',' : '.';
2193
+ }
2184
2194
  function useProvided(props, prop, provided) {
2185
2195
  const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
2186
2196
 
@@ -2203,6 +2213,7 @@ function createProvideFunction(state) {
2203
2213
  current,
2204
2214
  fallback,
2205
2215
  messages,
2216
+ decimalSeparator: toRef(() => inferDecimalSeparator(current, fallback)),
2206
2217
  t: createTranslateFunction(current, fallback, messages),
2207
2218
  n: createNumberFunction(current, fallback),
2208
2219
  provide: createProvideFunction({
@@ -2225,6 +2236,7 @@ function createVuetifyAdapter(options) {
2225
2236
  current,
2226
2237
  fallback,
2227
2238
  messages,
2239
+ decimalSeparator: toRef(() => options?.decimalSeparator ?? inferDecimalSeparator(current, fallback)),
2228
2240
  t: createTranslateFunction(current, fallback, messages),
2229
2241
  n: createNumberFunction(current, fallback),
2230
2242
  provide: createProvideFunction({
@@ -2351,6 +2363,7 @@ const makeThemeProps = propsFactory({
2351
2363
  function genDefaults$2() {
2352
2364
  return {
2353
2365
  defaultTheme: 'light',
2366
+ prefix: 'v-',
2354
2367
  variations: {
2355
2368
  colors: [],
2356
2369
  lighten: 0,
@@ -2388,8 +2401,8 @@ function genDefaults$2() {
2388
2401
  'activated-opacity': 0.12,
2389
2402
  'pressed-opacity': 0.12,
2390
2403
  'dragged-opacity': 0.08,
2391
- 'theme-kbd': '#212529',
2392
- 'theme-on-kbd': '#FFFFFF',
2404
+ 'theme-kbd': '#EEEEEE',
2405
+ 'theme-on-kbd': '#000000',
2393
2406
  'theme-code': '#F5F5F5',
2394
2407
  'theme-on-code': '#000000'
2395
2408
  }
@@ -2425,14 +2438,17 @@ function genDefaults$2() {
2425
2438
  'activated-opacity': 0.12,
2426
2439
  'pressed-opacity': 0.16,
2427
2440
  'dragged-opacity': 0.08,
2428
- 'theme-kbd': '#212529',
2441
+ 'theme-kbd': '#424242',
2429
2442
  'theme-on-kbd': '#FFFFFF',
2430
2443
  'theme-code': '#343434',
2431
2444
  'theme-on-code': '#CCCCCC'
2432
2445
  }
2433
2446
  }
2434
2447
  },
2435
- stylesheetId: 'vuetify-theme-stylesheet'
2448
+ stylesheetId: 'vuetify-theme-stylesheet',
2449
+ scoped: false,
2450
+ unimportant: false,
2451
+ utilities: true
2436
2452
  };
2437
2453
  }
2438
2454
  function parseThemeOptions() {
@@ -2455,21 +2471,21 @@ function parseThemeOptions() {
2455
2471
  function createCssClass(lines, selector, content, scope) {
2456
2472
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2457
2473
  }
2458
- function genCssVariables(theme) {
2474
+ function genCssVariables(theme, prefix) {
2459
2475
  const lightOverlay = theme.dark ? 2 : 1;
2460
2476
  const darkOverlay = theme.dark ? 1 : 2;
2461
2477
  const variables = [];
2462
2478
  for (const [key, value] of Object.entries(theme.colors)) {
2463
2479
  const rgb = parseColor(value);
2464
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2480
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2465
2481
  if (!key.startsWith('on-')) {
2466
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2482
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2467
2483
  }
2468
2484
  }
2469
2485
  for (const [key, value] of Object.entries(theme.variables)) {
2470
2486
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2471
2487
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2472
- variables.push(`--v-${key}: ${rgb ?? value}`);
2488
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2473
2489
  }
2474
2490
  return variables;
2475
2491
  }
@@ -2513,7 +2529,8 @@ function getScopedSelector(selector, scope) {
2513
2529
  const scopeSelector = `:where(${scope})`;
2514
2530
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2515
2531
  }
2516
- function upsertStyles(styleEl, styles) {
2532
+ function upsertStyles(id, cspNonce, styles) {
2533
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2517
2534
  if (!styleEl) return;
2518
2535
  styleEl.innerHTML = styles;
2519
2536
  }
@@ -2533,8 +2550,17 @@ function getOrCreateStyleElement(id, cspNonce) {
2533
2550
  // Composables
2534
2551
  function createTheme(options) {
2535
2552
  const parsedOptions = parseThemeOptions(options);
2536
- const name = shallowRef(parsedOptions.defaultTheme);
2553
+ const _name = shallowRef(parsedOptions.defaultTheme);
2537
2554
  const themes = ref(parsedOptions.themes);
2555
+ const systemName = shallowRef('light');
2556
+ const name = computed({
2557
+ get() {
2558
+ return _name.value === 'system' ? systemName.value : _name.value;
2559
+ },
2560
+ set(val) {
2561
+ _name.value = val;
2562
+ }
2563
+ });
2538
2564
  const computedThemes = computed(() => {
2539
2565
  const acc = {};
2540
2566
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2555,28 +2581,49 @@ function createTheme(options) {
2555
2581
  const current = toRef(() => computedThemes.value[name.value]);
2556
2582
  const styles = computed(() => {
2557
2583
  const lines = [];
2584
+ const important = parsedOptions.unimportant ? '' : ' !important';
2585
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2558
2586
  if (current.value?.dark) {
2559
2587
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2560
2588
  }
2561
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2589
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2562
2590
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2563
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2564
- }
2565
- const bgLines = [];
2566
- const fgLines = [];
2567
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2568
- for (const key of colors) {
2569
- if (key.startsWith('on-')) {
2570
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2571
- } else {
2572
- 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);
2573
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2574
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2591
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2592
+ }
2593
+ if (parsedOptions.utilities) {
2594
+ const bgLines = [];
2595
+ const fgLines = [];
2596
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2597
+ for (const key of colors) {
2598
+ if (key.startsWith('on-')) {
2599
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2600
+ } else {
2601
+ 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);
2602
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2603
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2604
+ }
2575
2605
  }
2606
+ lines.push(...bgLines, ...fgLines);
2576
2607
  }
2577
- lines.push(...bgLines, ...fgLines);
2578
2608
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2579
2609
  });
2610
+ const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2611
+ const themeNames = toRef(() => Object.keys(computedThemes.value));
2612
+ if (SUPPORTS_MATCH_MEDIA) {
2613
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2614
+ function updateSystemName() {
2615
+ systemName.value = media.matches ? 'dark' : 'light';
2616
+ }
2617
+ updateSystemName();
2618
+ media.addEventListener('change', updateSystemName, {
2619
+ passive: true
2620
+ });
2621
+ if (getCurrentScope()) {
2622
+ onScopeDispose(() => {
2623
+ media.removeEventListener('change', updateSystemName);
2624
+ });
2625
+ }
2626
+ }
2580
2627
  function install(app) {
2581
2628
  if (parsedOptions.isDisabled) return;
2582
2629
  const head = app._context.provides.usehead;
@@ -2614,22 +2661,55 @@ function createTheme(options) {
2614
2661
  updateStyles();
2615
2662
  }
2616
2663
  function updateStyles() {
2617
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2664
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2618
2665
  }
2619
2666
  }
2620
2667
  }
2621
- const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2668
+ function change(themeName) {
2669
+ if (!themeNames.value.includes(themeName)) {
2670
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2671
+ return;
2672
+ }
2673
+ name.value = themeName;
2674
+ }
2675
+ function cycle() {
2676
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2677
+ const currentIndex = themeArray.indexOf(name.value);
2678
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2679
+ change(themeArray[nextIndex]);
2680
+ }
2681
+ function toggle() {
2682
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2683
+ cycle(themeArray);
2684
+ }
2685
+ const globalName = new Proxy(name, {
2686
+ get(target, prop) {
2687
+ return target[prop];
2688
+ },
2689
+ set(target, prop, val) {
2690
+ if (prop === 'value') {
2691
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2692
+ }
2693
+ // @ts-expect-error
2694
+ target[prop] = val;
2695
+ return true;
2696
+ }
2697
+ });
2622
2698
  return {
2623
2699
  install,
2700
+ change,
2701
+ cycle,
2702
+ toggle,
2624
2703
  isDisabled: parsedOptions.isDisabled,
2625
2704
  name,
2626
2705
  themes,
2627
2706
  current,
2628
2707
  computedThemes,
2708
+ prefix: parsedOptions.prefix,
2629
2709
  themeClasses,
2630
2710
  styles,
2631
2711
  global: {
2632
- name,
2712
+ name: globalName,
2633
2713
  current
2634
2714
  }
2635
2715
  };
@@ -2640,7 +2720,7 @@ function provideTheme(props) {
2640
2720
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2641
2721
  const name = toRef(() => props.theme ?? theme.name.value);
2642
2722
  const current = toRef(() => theme.themes.value[name.value]);
2643
- const themeClasses = toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2723
+ const themeClasses = toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2644
2724
  const newTheme = {
2645
2725
  ...theme,
2646
2726
  name,
@@ -3744,7 +3824,10 @@ const makeVToolbarProps = propsFactory({
3744
3824
  default: 'default',
3745
3825
  validator: v => allowedDensities$1.includes(v)
3746
3826
  },
3747
- extended: Boolean,
3827
+ extended: {
3828
+ type: Boolean,
3829
+ default: null
3830
+ },
3748
3831
  extensionHeight: {
3749
3832
  type: [Number, String],
3750
3833
  default: 48
@@ -3792,7 +3875,7 @@ const VToolbar = genericComponent()({
3792
3875
  const {
3793
3876
  rtlClasses
3794
3877
  } = useRtl();
3795
- const isExtended = shallowRef(!!(props.extended || slots.extension?.()));
3878
+ const isExtended = shallowRef(props.extended === null ? !!slots.extension?.() : props.extended);
3796
3879
  const contentHeight = computed(() => parseInt(Number(props.height) + (props.density === 'prominent' ? Number(props.height) : 0) - (props.density === 'comfortable' ? 8 : 0) - (props.density === 'compact' ? 16 : 0), 10));
3797
3880
  const extensionHeight = 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);
3798
3881
  provideDefaults({
@@ -3804,7 +3887,7 @@ const VToolbar = genericComponent()({
3804
3887
  const hasTitle = !!(props.title || slots.title);
3805
3888
  const hasImage = !!(slots.image || props.image);
3806
3889
  const extension = slots.extension?.();
3807
- isExtended.value = !!(props.extended || extension);
3890
+ isExtended.value = props.extended === null ? !!extension : props.extended;
3808
3891
  return createVNode(props.tag, {
3809
3892
  "class": normalizeClass(['v-toolbar', {
3810
3893
  'v-toolbar--absolute': props.absolute,
@@ -4187,9 +4270,15 @@ function useVariant(props) {
4187
4270
  };
4188
4271
  }
4189
4272
 
4273
+ // Types
4274
+
4190
4275
  const makeVBtnGroupProps = propsFactory({
4191
4276
  baseColor: String,
4192
4277
  divided: Boolean,
4278
+ direction: {
4279
+ type: String,
4280
+ default: 'horizontal'
4281
+ },
4193
4282
  ...makeBorderProps(),
4194
4283
  ...makeComponentProps(),
4195
4284
  ...makeDensityProps(),
@@ -4223,7 +4312,7 @@ const VBtnGroup = genericComponent()({
4223
4312
  } = useRounded(props);
4224
4313
  provideDefaults({
4225
4314
  VBtn: {
4226
- height: 'auto',
4315
+ height: toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4227
4316
  baseColor: toRef(() => props.baseColor),
4228
4317
  color: toRef(() => props.color),
4229
4318
  density: toRef(() => props.density),
@@ -4233,7 +4322,7 @@ const VBtnGroup = genericComponent()({
4233
4322
  });
4234
4323
  useRender(() => {
4235
4324
  return createVNode(props.tag, {
4236
- "class": normalizeClass(['v-btn-group', {
4325
+ "class": normalizeClass(['v-btn-group', `v-btn-group--${props.direction}`, {
4237
4326
  'v-btn-group--divided': props.divided
4238
4327
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
4239
4328
  "style": normalizeStyle(props.style)
@@ -4400,6 +4489,7 @@ function useGroup(props, injectKey) {
4400
4489
  } else {
4401
4490
  const isSelected = selected.value.includes(id);
4402
4491
  if (props.mandatory && isSelected) return;
4492
+ if (!isSelected && !value) return;
4403
4493
  selected.value = value ?? !isSelected ? [id] : [];
4404
4494
  }
4405
4495
  }
@@ -4834,7 +4924,7 @@ function useIntersectionObserver(callback, options) {
4834
4924
  const observer = new IntersectionObserver(entries => {
4835
4925
  isIntersecting.value = !!entries.find(entry => entry.isIntersecting);
4836
4926
  }, options);
4837
- onBeforeUnmount(() => {
4927
+ onScopeDispose(() => {
4838
4928
  observer.disconnect();
4839
4929
  });
4840
4930
  watch(intersectionRef, (newValue, oldValue) => {
@@ -5365,9 +5455,9 @@ function useBackButton(router, cb) {
5365
5455
 
5366
5456
  function useSelectLink(link, select) {
5367
5457
  watch(() => link.isActive?.value, isActive => {
5368
- if (link.isLink.value && isActive && select) {
5458
+ if (link.isLink.value && isActive != null && select) {
5369
5459
  nextTick(() => {
5370
- select(true);
5460
+ select(isActive);
5371
5461
  });
5372
5462
  }
5373
5463
  }, {
@@ -5565,8 +5655,8 @@ function rippleCancelShow(e) {
5565
5655
  window.clearTimeout(element._ripple.showTimer);
5566
5656
  }
5567
5657
  let keyboardRipple = false;
5568
- function keyboardRippleShow(e) {
5569
- if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
5658
+ function keyboardRippleShow(e, keys) {
5659
+ if (!keyboardRipple && keys.includes(e.keyCode)) {
5570
5660
  keyboardRipple = true;
5571
5661
  rippleShow(e);
5572
5662
  }
@@ -5594,9 +5684,12 @@ function updateRipple(el, binding, wasEnabled) {
5594
5684
  el._ripple.enabled = enabled;
5595
5685
  el._ripple.centered = modifiers.center;
5596
5686
  el._ripple.circle = modifiers.circle;
5597
- if (isObject(value) && value.class) {
5598
- el._ripple.class = value.class;
5687
+ const bindingValue = isObject(value) ? value : {};
5688
+ if (bindingValue.class) {
5689
+ el._ripple.class = bindingValue.class;
5599
5690
  }
5691
+ const allowedKeys = bindingValue.keys ?? [keyCodes.enter, keyCodes.space];
5692
+ el._ripple.keyDownHandler = e => keyboardRippleShow(e, allowedKeys);
5600
5693
  if (enabled && !wasEnabled) {
5601
5694
  if (modifiers.stop) {
5602
5695
  el.addEventListener('touchstart', rippleStop, {
@@ -5618,7 +5711,7 @@ function updateRipple(el, binding, wasEnabled) {
5618
5711
  el.addEventListener('mousedown', rippleShow);
5619
5712
  el.addEventListener('mouseup', rippleHide);
5620
5713
  el.addEventListener('mouseleave', rippleHide);
5621
- el.addEventListener('keydown', keyboardRippleShow);
5714
+ el.addEventListener('keydown', e => keyboardRippleShow(e, allowedKeys));
5622
5715
  el.addEventListener('keyup', keyboardRippleHide);
5623
5716
  el.addEventListener('blur', focusRippleHide);
5624
5717
 
@@ -5638,7 +5731,9 @@ function removeListeners(el) {
5638
5731
  el.removeEventListener('touchcancel', rippleHide);
5639
5732
  el.removeEventListener('mouseup', rippleHide);
5640
5733
  el.removeEventListener('mouseleave', rippleHide);
5641
- el.removeEventListener('keydown', keyboardRippleShow);
5734
+ if (el._ripple?.keyDownHandler) {
5735
+ el.removeEventListener('keydown', el._ripple.keyDownHandler);
5736
+ }
5642
5737
  el.removeEventListener('keyup', keyboardRippleHide);
5643
5738
  el.removeEventListener('dragstart', rippleHide);
5644
5739
  el.removeEventListener('blur', focusRippleHide);
@@ -5647,8 +5742,8 @@ function mounted$4(el, binding) {
5647
5742
  updateRipple(el, binding, false);
5648
5743
  }
5649
5744
  function unmounted$4(el) {
5650
- delete el._ripple;
5651
5745
  removeListeners(el);
5746
+ delete el._ripple;
5652
5747
  }
5653
5748
  function updated$1(el, binding) {
5654
5749
  if (binding.value === binding.oldValue) {
@@ -5921,6 +6016,31 @@ const VAppBarTitle = genericComponent()({
5921
6016
  // Utilities
5922
6017
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5923
6018
 
6019
+ // Utilities
6020
+
6021
+ // Types
6022
+
6023
+ // Types
6024
+
6025
+ // Composables
6026
+ const makeIconSizeProps = propsFactory({
6027
+ iconSize: [Number, String],
6028
+ iconSizes: {
6029
+ type: Array,
6030
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6031
+ }
6032
+ }, 'iconSize');
6033
+ function useIconSizes(props, fallback) {
6034
+ const iconSize = computed(() => {
6035
+ const iconSizeMap = new Map(props.iconSizes);
6036
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6037
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6038
+ });
6039
+ return {
6040
+ iconSize
6041
+ };
6042
+ }
6043
+
5924
6044
  // Types
5925
6045
 
5926
6046
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5960,6 +6080,7 @@ const makeVAlertProps = propsFactory({
5960
6080
  ...makeDensityProps(),
5961
6081
  ...makeDimensionProps(),
5962
6082
  ...makeElevationProps(),
6083
+ ...makeIconSizeProps(),
5963
6084
  ...makeLocationProps(),
5964
6085
  ...makePositionProps(),
5965
6086
  ...makeRoundedProps(),
@@ -5987,6 +6108,9 @@ const VAlert = genericComponent()({
5987
6108
  if (!props.type) return props.icon;
5988
6109
  return props.icon ?? `$${props.type}`;
5989
6110
  });
6111
+ const {
6112
+ iconSize
6113
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5990
6114
  const {
5991
6115
  themeClasses
5992
6116
  } = provideTheme(props);
@@ -6034,6 +6158,11 @@ const VAlert = genericComponent()({
6034
6158
  const hasPrepend = !!(slots.prepend || icon.value);
6035
6159
  const hasTitle = !!(slots.title || props.title);
6036
6160
  const hasClose = !!(slots.close || props.closable);
6161
+ const iconProps = {
6162
+ density: props.density,
6163
+ icon: icon.value,
6164
+ size: iconSize.value
6165
+ };
6037
6166
  return isActive.value && createVNode(props.tag, {
6038
6167
  "class": normalizeClass(['v-alert', props.border && {
6039
6168
  'v-alert--border': !!props.border,
@@ -6051,19 +6180,14 @@ const VAlert = genericComponent()({
6051
6180
  }, null), hasPrepend && createElementVNode("div", {
6052
6181
  "key": "prepend",
6053
6182
  "class": "v-alert__prepend"
6054
- }, [!slots.prepend ? createVNode(VIcon, {
6055
- "key": "prepend-icon",
6056
- "density": props.density,
6057
- "icon": icon.value,
6058
- "size": props.prominent ? 44 : 28
6059
- }, null) : createVNode(VDefaultsProvider, {
6183
+ }, [!slots.prepend ? createVNode(VIcon, mergeProps({
6184
+ "key": "prepend-icon"
6185
+ }, iconProps), null) : createVNode(VDefaultsProvider, {
6060
6186
  "key": "prepend-defaults",
6061
6187
  "disabled": !icon.value,
6062
6188
  "defaults": {
6063
6189
  VIcon: {
6064
- density: props.density,
6065
- icon: icon.value,
6066
- size: props.prominent ? 44 : 28
6190
+ ...iconProps
6067
6191
  }
6068
6192
  }
6069
6193
  }, slots.prepend)]), createElementVNode("div", {
@@ -7588,6 +7712,7 @@ function getOffsetPosition(isHorizontal, element) {
7588
7712
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7589
7713
  const makeVSlideGroupProps = propsFactory({
7590
7714
  centerActive: Boolean,
7715
+ contentClass: null,
7591
7716
  direction: {
7592
7717
  type: String,
7593
7718
  default: 'horizontal'
@@ -7900,7 +8025,7 @@ const VSlideGroup = genericComponent()({
7900
8025
  })]), createElementVNode("div", {
7901
8026
  "key": "container",
7902
8027
  "ref": containerRef,
7903
- "class": "v-slide-group__container",
8028
+ "class": normalizeClass(['v-slide-group__container', props.contentClass]),
7904
8029
  "onScroll": onScroll
7905
8030
  }, [createElementVNode("div", {
7906
8031
  "ref": contentRef,
@@ -8263,16 +8388,85 @@ const VChip = genericComponent()({
8263
8388
  }
8264
8389
  });
8265
8390
 
8391
+ const makeVDividerProps = propsFactory({
8392
+ color: String,
8393
+ inset: Boolean,
8394
+ length: [Number, String],
8395
+ opacity: [Number, String],
8396
+ thickness: [Number, String],
8397
+ vertical: Boolean,
8398
+ ...makeComponentProps(),
8399
+ ...makeThemeProps()
8400
+ }, 'VDivider');
8401
+ const VDivider = genericComponent()({
8402
+ name: 'VDivider',
8403
+ props: makeVDividerProps(),
8404
+ setup(props, _ref) {
8405
+ let {
8406
+ attrs,
8407
+ slots
8408
+ } = _ref;
8409
+ const {
8410
+ themeClasses
8411
+ } = provideTheme(props);
8412
+ const {
8413
+ textColorClasses,
8414
+ textColorStyles
8415
+ } = useTextColor(() => props.color);
8416
+ const dividerStyles = computed(() => {
8417
+ const styles = {};
8418
+ if (props.length) {
8419
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8420
+ }
8421
+ if (props.thickness) {
8422
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8423
+ }
8424
+ return styles;
8425
+ });
8426
+ useRender(() => {
8427
+ const divider = createElementVNode("hr", {
8428
+ "class": normalizeClass([{
8429
+ 'v-divider': true,
8430
+ 'v-divider--inset': props.inset,
8431
+ 'v-divider--vertical': props.vertical
8432
+ }, themeClasses.value, textColorClasses.value, props.class]),
8433
+ "style": normalizeStyle([dividerStyles.value, textColorStyles.value, {
8434
+ '--v-border-opacity': props.opacity
8435
+ }, props.style]),
8436
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8437
+ "role": `${attrs.role || 'separator'}`
8438
+ }, null);
8439
+ if (!slots.default) return divider;
8440
+ return createElementVNode("div", {
8441
+ "class": normalizeClass(['v-divider__wrapper', {
8442
+ 'v-divider__wrapper--vertical': props.vertical,
8443
+ 'v-divider__wrapper--inset': props.inset
8444
+ }])
8445
+ }, [divider, createElementVNode("div", {
8446
+ "class": "v-divider__content"
8447
+ }, [slots.default()]), divider]);
8448
+ });
8449
+ return {};
8450
+ }
8451
+ });
8452
+
8266
8453
  // Utilities
8267
8454
 
8268
8455
  // List
8269
8456
  const ListKey = Symbol.for('vuetify:list');
8270
8457
  function createList() {
8458
+ let {
8459
+ filterable
8460
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
8461
+ filterable: false
8462
+ };
8271
8463
  const parent = inject$1(ListKey, {
8464
+ filterable: false,
8272
8465
  hasPrepend: shallowRef(false),
8273
8466
  updateHasPrepend: () => null
8274
8467
  });
8275
8468
  const data = {
8469
+ filterable: parent.filterable || filterable,
8276
8470
  hasPrepend: shallowRef(false),
8277
8471
  updateHasPrepend: value => {
8278
8472
  if (value) data.hasPrepend.value = value;
@@ -8981,6 +9175,7 @@ const makeVListGroupProps = propsFactory({
8981
9175
  type: IconValue,
8982
9176
  default: '$expand'
8983
9177
  },
9178
+ rawId: [String, Number],
8984
9179
  prependIcon: IconValue,
8985
9180
  appendIcon: IconValue,
8986
9181
  fluid: Boolean,
@@ -9002,13 +9197,12 @@ const VListGroup = genericComponent()({
9002
9197
  open,
9003
9198
  id: _id
9004
9199
  } = useNestedItem(() => props.value, true);
9005
- const id = computed(() => `v-list-group--id-${String(_id.value)}`);
9200
+ const id = computed(() => `v-list-group--id-${String(props.rawId ?? _id.value)}`);
9006
9201
  const list = useList();
9007
9202
  const {
9008
9203
  isBooted
9009
9204
  } = useSsrBoot();
9010
9205
  function onClick(e) {
9011
- e.stopPropagation();
9012
9206
  if (['INPUT', 'TEXTAREA'].includes(e.target?.tagName)) return;
9013
9207
  open(!isOpen.value, e);
9014
9208
  }
@@ -9224,6 +9418,9 @@ const VListItem = genericComponent()({
9224
9418
  roundedClasses
9225
9419
  } = useRounded(roundedProps);
9226
9420
  const lineClasses = toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
9421
+ const rippleOptions = toRef(() => props.ripple !== undefined && !!props.ripple && list?.filterable ? {
9422
+ keys: [keyCodes.enter]
9423
+ } : props.ripple);
9227
9424
  const slotProps = computed(() => ({
9228
9425
  isActive: isActive.value,
9229
9426
  select,
@@ -9248,8 +9445,9 @@ const VListItem = genericComponent()({
9248
9445
  function onKeyDown(e) {
9249
9446
  const target = e.target;
9250
9447
  if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
9251
- if (e.key === 'Enter' || e.key === ' ') {
9448
+ if (e.key === 'Enter' || e.key === ' ' && !list?.filterable) {
9252
9449
  e.preventDefault();
9450
+ e.stopPropagation();
9253
9451
  e.target.dispatchEvent(new MouseEvent('click', e));
9254
9452
  }
9255
9453
  }
@@ -9359,7 +9557,7 @@ const VListItem = genericComponent()({
9359
9557
  }), createElementVNode("div", {
9360
9558
  "class": "v-list-item__spacer"
9361
9559
  }, null)])]
9362
- }), [[Ripple, isClickable.value && props.ripple]]);
9560
+ }), [[Ripple, isClickable.value && rippleOptions.value]]);
9363
9561
  });
9364
9562
  return {
9365
9563
  activate,
@@ -9414,68 +9612,6 @@ const VListSubheader = genericComponent()({
9414
9612
  }
9415
9613
  });
9416
9614
 
9417
- const makeVDividerProps = propsFactory({
9418
- color: String,
9419
- inset: Boolean,
9420
- length: [Number, String],
9421
- opacity: [Number, String],
9422
- thickness: [Number, String],
9423
- vertical: Boolean,
9424
- ...makeComponentProps(),
9425
- ...makeThemeProps()
9426
- }, 'VDivider');
9427
- const VDivider = genericComponent()({
9428
- name: 'VDivider',
9429
- props: makeVDividerProps(),
9430
- setup(props, _ref) {
9431
- let {
9432
- attrs,
9433
- slots
9434
- } = _ref;
9435
- const {
9436
- themeClasses
9437
- } = provideTheme(props);
9438
- const {
9439
- textColorClasses,
9440
- textColorStyles
9441
- } = useTextColor(() => props.color);
9442
- const dividerStyles = computed(() => {
9443
- const styles = {};
9444
- if (props.length) {
9445
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9446
- }
9447
- if (props.thickness) {
9448
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9449
- }
9450
- return styles;
9451
- });
9452
- useRender(() => {
9453
- const divider = createElementVNode("hr", {
9454
- "class": normalizeClass([{
9455
- 'v-divider': true,
9456
- 'v-divider--inset': props.inset,
9457
- 'v-divider--vertical': props.vertical
9458
- }, themeClasses.value, textColorClasses.value, props.class]),
9459
- "style": normalizeStyle([dividerStyles.value, textColorStyles.value, {
9460
- '--v-border-opacity': props.opacity
9461
- }, props.style]),
9462
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9463
- "role": `${attrs.role || 'separator'}`
9464
- }, null);
9465
- if (!slots.default) return divider;
9466
- return createElementVNode("div", {
9467
- "class": normalizeClass(['v-divider__wrapper', {
9468
- 'v-divider__wrapper--vertical': props.vertical,
9469
- 'v-divider__wrapper--inset': props.inset
9470
- }])
9471
- }, [divider, createElementVNode("div", {
9472
- "class": "v-divider__content"
9473
- }, [slots.default()]), divider]);
9474
- });
9475
- return {};
9476
- }
9477
- });
9478
-
9479
9615
  // Types
9480
9616
 
9481
9617
  const makeVListChildrenProps = propsFactory({
@@ -9526,9 +9662,10 @@ const VListChildren = genericComponent()({
9526
9662
  }) : undefined
9527
9663
  };
9528
9664
  const listGroupProps = VListGroup.filterProps(itemProps);
9529
- return children ? createVNode(VListGroup, mergeProps({
9530
- "value": itemProps?.value
9531
- }, listGroupProps), {
9665
+ return children ? createVNode(VListGroup, mergeProps(listGroupProps, {
9666
+ "value": props.returnObject ? item : itemProps?.value,
9667
+ "rawId": itemProps?.value
9668
+ }), {
9532
9669
  activator: _ref3 => {
9533
9670
  let {
9534
9671
  props: activatorProps
@@ -9744,6 +9881,7 @@ const makeVListProps = propsFactory({
9744
9881
  activeClass: String,
9745
9882
  bgColor: String,
9746
9883
  disabled: Boolean,
9884
+ filterable: Boolean,
9747
9885
  expandIcon: IconValue,
9748
9886
  collapseIcon: IconValue,
9749
9887
  lines: {
@@ -9827,7 +9965,9 @@ const VList = genericComponent()({
9827
9965
  const activeColor = toRef(() => props.activeColor);
9828
9966
  const baseColor = toRef(() => props.baseColor);
9829
9967
  const color = toRef(() => props.color);
9830
- createList();
9968
+ createList({
9969
+ filterable: props.filterable
9970
+ });
9831
9971
  provideDefaults({
9832
9972
  VListGroup: {
9833
9973
  activeColor,
@@ -11510,6 +11650,7 @@ const makeVMenuProps = propsFactory({
11510
11650
  // disableKeys: Boolean,
11511
11651
  id: String,
11512
11652
  submenu: Boolean,
11653
+ disableInitialFocus: Boolean,
11513
11654
  ...omit(makeVOverlayProps({
11514
11655
  closeDelay: 250,
11515
11656
  closeOnContentClick: true,
@@ -11584,7 +11725,7 @@ const VMenu = genericComponent()({
11584
11725
  watch(isActive, val => {
11585
11726
  if (val) {
11586
11727
  parent?.register();
11587
- if (IN_BROWSER) {
11728
+ if (IN_BROWSER && !props.disableInitialFocus) {
11588
11729
  document.addEventListener('focusin', onFocusIn, {
11589
11730
  once: true
11590
11731
  });
@@ -12064,6 +12205,16 @@ const VField = genericComponent()({
12064
12205
  }
12065
12206
  });
12066
12207
 
12208
+ function useAutofocus(props) {
12209
+ function onIntersect(isIntersecting, entries) {
12210
+ if (!props.autofocus || !isIntersecting) return;
12211
+ entries[0].target?.focus?.();
12212
+ }
12213
+ return {
12214
+ onIntersect
12215
+ };
12216
+ }
12217
+
12067
12218
  // Types
12068
12219
 
12069
12220
  const activeTypes = ['color', 'file', 'time', 'date', 'datetime-local', 'week', 'month'];
@@ -12110,6 +12261,9 @@ const VTextField = genericComponent()({
12110
12261
  focus,
12111
12262
  blur
12112
12263
  } = useFocus(props);
12264
+ const {
12265
+ onIntersect
12266
+ } = useAutofocus(props);
12113
12267
  const counterValue = computed(() => {
12114
12268
  return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : (model.value ?? '').toString().length;
12115
12269
  });
@@ -12119,10 +12273,6 @@ const VTextField = genericComponent()({
12119
12273
  return props.counter;
12120
12274
  });
12121
12275
  const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
12122
- function onIntersect(isIntersecting, entries) {
12123
- if (!props.autofocus || !isIntersecting) return;
12124
- entries[0].target?.focus?.();
12125
- }
12126
12276
  const vInputRef = ref();
12127
12277
  const vFieldRef = ref();
12128
12278
  const inputRef = ref();
@@ -12412,7 +12562,12 @@ function useVirtual(props, items) {
12412
12562
  }
12413
12563
  function calculateOffset(index) {
12414
12564
  index = clamp(index, 0, items.value.length - 1);
12415
- return offsets[index] || 0;
12565
+ const whole = Math.floor(index);
12566
+ const fraction = index % 1;
12567
+ const next = whole + 1;
12568
+ const wholeOffset = offsets[whole] || 0;
12569
+ const nextOffset = offsets[next] || wholeOffset;
12570
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12416
12571
  }
12417
12572
  function calculateIndex(scrollTop) {
12418
12573
  return binaryClosest(offsets, scrollTop);
@@ -12766,6 +12921,7 @@ const makeSelectProps = propsFactory({
12766
12921
  },
12767
12922
  openOnClear: Boolean,
12768
12923
  itemColor: String,
12924
+ noAutoScroll: Boolean,
12769
12925
  ...makeItemsProps({
12770
12926
  itemChildren: false
12771
12927
  })
@@ -12980,7 +13136,7 @@ const VSelect = genericComponent()({
12980
13136
  watch(menu, () => {
12981
13137
  if (!props.hideSelected && menu.value && model.value.length) {
12982
13138
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
12983
- IN_BROWSER && window.requestAnimationFrame(() => {
13139
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
12984
13140
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
12985
13141
  });
12986
13142
  }
@@ -13073,6 +13229,22 @@ const VSelect = genericComponent()({
13073
13229
  key: item.value,
13074
13230
  onClick: () => select(item, null)
13075
13231
  });
13232
+ if (item.raw.type === 'divider') {
13233
+ return slots.divider?.({
13234
+ props: item.raw,
13235
+ index
13236
+ }) ?? createVNode(VDivider, mergeProps(item.props, {
13237
+ "key": `divider-${index}`
13238
+ }), null);
13239
+ }
13240
+ if (item.raw.type === 'subheader') {
13241
+ return slots.subheader?.({
13242
+ props: item.raw,
13243
+ index
13244
+ }) ?? createVNode(VListSubheader, mergeProps(item.props, {
13245
+ "key": `subheader-${index}`
13246
+ }), null);
13247
+ }
13076
13248
  return slots.item?.({
13077
13249
  item,
13078
13250
  index,
@@ -13233,6 +13405,9 @@ function filterItems(items, query, options) {
13233
13405
  let match = -1;
13234
13406
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13235
13407
  if (typeof item === 'object') {
13408
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13409
+ continue;
13410
+ }
13236
13411
  const filterKeys = keys || Object.keys(transformed);
13237
13412
  for (const key of filterKeys) {
13238
13413
  const value = getPropertyFromItem(transformed, key);
@@ -13435,7 +13610,7 @@ const VAutocomplete = genericComponent()({
13435
13610
  menu.value = !menu.value;
13436
13611
  }
13437
13612
  function onListKeydown(e) {
13438
- if (e.key !== ' ' && checkPrintable(e)) {
13613
+ if (checkPrintable(e) || e.key === 'Backspace') {
13439
13614
  vTextFieldRef.value?.focus();
13440
13615
  }
13441
13616
  }
@@ -13640,6 +13815,7 @@ const VAutocomplete = genericComponent()({
13640
13815
  }, props.menuProps), {
13641
13816
  default: () => [hasList && createVNode(VList, mergeProps({
13642
13817
  "ref": listRef,
13818
+ "filterable": true,
13643
13819
  "selected": selectedValues.value,
13644
13820
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
13645
13821
  "onMousedown": e => e.preventDefault(),
@@ -13671,6 +13847,22 @@ const VAutocomplete = genericComponent()({
13671
13847
  active: highlightFirst.value && index === 0 ? true : undefined,
13672
13848
  onClick: () => select(item, null)
13673
13849
  });
13850
+ if (item.raw.type === 'divider') {
13851
+ return slots.divider?.({
13852
+ props: item.raw,
13853
+ index
13854
+ }) ?? createVNode(VDivider, mergeProps(item.props, {
13855
+ "key": `divider-${index}`
13856
+ }), null);
13857
+ }
13858
+ if (item.raw.type === 'subheader') {
13859
+ return slots.subheader?.({
13860
+ props: item.raw,
13861
+ index
13862
+ }) ?? createVNode(VListSubheader, mergeProps(item.props, {
13863
+ "key": `subheader-${index}`
13864
+ }), null);
13865
+ }
13674
13866
  return slots.item?.({
13675
13867
  item,
13676
13868
  index,
@@ -13815,7 +14007,8 @@ const makeVBadgeProps = propsFactory({
13815
14007
  ...makeThemeProps(),
13816
14008
  ...makeTransitionProps({
13817
14009
  transition: 'scale-rotate-transition'
13818
- })
14010
+ }),
14011
+ ...makeDimensionProps()
13819
14012
  }, 'VBadge');
13820
14013
  const VBadge = genericComponent()({
13821
14014
  name: 'VBadge',
@@ -13845,6 +14038,9 @@ const VBadge = genericComponent()({
13845
14038
  const base = props.floating ? props.dot ? 2 : 4 : props.dot ? 8 : 12;
13846
14039
  return base + (['top', 'bottom'].includes(side) ? Number(props.offsetY ?? 0) : ['left', 'right'].includes(side) ? Number(props.offsetX ?? 0) : 0);
13847
14040
  });
14041
+ const {
14042
+ dimensionStyles
14043
+ } = useDimension(props);
13848
14044
  useRender(() => {
13849
14045
  const value = Number(props.content);
13850
14046
  const content = !props.max || isNaN(value) ? props.content : value <= Number(props.max) ? value : `${props.max}+`;
@@ -13866,7 +14062,7 @@ const VBadge = genericComponent()({
13866
14062
  }, {
13867
14063
  default: () => [withDirectives(createElementVNode("span", mergeProps({
13868
14064
  "class": ['v-badge__badge', themeClasses.value, backgroundColorClasses.value, roundedClasses.value, textColorClasses.value],
13869
- "style": [backgroundColorStyles.value, textColorStyles.value, props.inline ? {} : locationStyles.value],
14065
+ "style": [backgroundColorStyles.value, textColorStyles.value, dimensionStyles.value, props.inline ? {} : locationStyles.value],
13870
14066
  "aria-atomic": "true",
13871
14067
  "aria-label": t(props.label, value),
13872
14068
  "aria-live": "polite",
@@ -17275,13 +17471,13 @@ function date(value) {
17275
17471
  return null;
17276
17472
  }
17277
17473
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17278
- function getWeekdays(locale, firstDayOfWeek) {
17474
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17279
17475
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17280
17476
  return createRange(7).map(i => {
17281
17477
  const weekday = new Date(sundayJanuarySecond2000);
17282
17478
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17283
17479
  return new Intl.DateTimeFormat(locale, {
17284
- weekday: 'narrow'
17480
+ weekday: weekdayFormat ?? 'narrow'
17285
17481
  }).format(weekday);
17286
17482
  });
17287
17483
  }
@@ -17745,9 +17941,9 @@ class VuetifyDateAdapter {
17745
17941
  getDiff(date, comparing, unit) {
17746
17942
  return getDiff(date, comparing, unit);
17747
17943
  }
17748
- getWeekdays(firstDayOfWeek) {
17944
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17749
17945
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17750
- return getWeekdays(this.locale, firstDay);
17946
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17751
17947
  }
17752
17948
  getYear(date) {
17753
17949
  return getYear(date);
@@ -18102,6 +18298,7 @@ const VCombobox = genericComponent()({
18102
18298
  _search.value = val ?? '';
18103
18299
  if (!props.multiple && !hasSelectionSlot.value) {
18104
18300
  model.value = [transformItem$3(props, val)];
18301
+ nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18105
18302
  }
18106
18303
  if (val && props.multiple && props.delimiters?.length) {
18107
18304
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18182,7 +18379,7 @@ const VCombobox = genericComponent()({
18182
18379
  menu.value = !menu.value;
18183
18380
  }
18184
18381
  function onListKeydown(e) {
18185
- if (e.key !== ' ' && checkPrintable(e)) {
18382
+ if (checkPrintable(e) || e.key === 'Backspace') {
18186
18383
  vTextFieldRef.value?.focus();
18187
18384
  }
18188
18385
  }
@@ -18387,6 +18584,7 @@ const VCombobox = genericComponent()({
18387
18584
  }, props.menuProps), {
18388
18585
  default: () => [hasList && createVNode(VList, mergeProps({
18389
18586
  "ref": listRef,
18587
+ "filterable": true,
18390
18588
  "selected": selectedValues.value,
18391
18589
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18392
18590
  "onMousedown": e => e.preventDefault(),
@@ -18418,6 +18616,22 @@ const VCombobox = genericComponent()({
18418
18616
  active: highlightFirst.value && index === 0 ? true : undefined,
18419
18617
  onClick: () => select(item, null)
18420
18618
  });
18619
+ if (item.raw.type === 'divider') {
18620
+ return slots.divider?.({
18621
+ props: item.raw,
18622
+ index
18623
+ }) ?? createVNode(VDivider, mergeProps(item.props, {
18624
+ "key": `divider-${index}`
18625
+ }), null);
18626
+ }
18627
+ if (item.raw.type === 'subheader') {
18628
+ return slots.subheader?.({
18629
+ props: item.raw,
18630
+ index
18631
+ }) ?? createVNode(VListSubheader, mergeProps(item.props, {
18632
+ "key": `subheader-${index}`
18633
+ }), null);
18634
+ }
18421
18635
  return slots.item?.({
18422
18636
  item,
18423
18637
  index,
@@ -20300,6 +20514,7 @@ const makeVDataTableHeadersProps = propsFactory({
20300
20514
  color: String,
20301
20515
  disableSort: Boolean,
20302
20516
  fixedHeader: Boolean,
20517
+ lastFixed: Boolean,
20303
20518
  multiSort: Boolean,
20304
20519
  sortAscIcon: {
20305
20520
  type: IconValue,
@@ -20346,10 +20561,11 @@ const VDataTableHeaders = genericComponent()({
20346
20561
  loaderClasses
20347
20562
  } = useLoader(props);
20348
20563
  function getFixedStyles(column, y) {
20349
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20564
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20350
20565
  return {
20351
20566
  position: 'sticky',
20352
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20567
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20568
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20353
20569
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20354
20570
  };
20355
20571
  }
@@ -20865,11 +21081,18 @@ const VDataTableRows = genericComponent()({
20865
21081
  }
20866
21082
  });
20867
21083
 
21084
+ // Types
21085
+
20868
21086
  const makeVTableProps = propsFactory({
20869
21087
  fixedHeader: Boolean,
20870
21088
  fixedFooter: Boolean,
20871
21089
  height: [Number, String],
20872
21090
  hover: Boolean,
21091
+ striped: {
21092
+ type: String,
21093
+ default: null,
21094
+ validator: v => ['even', 'odd'].includes(v)
21095
+ },
20873
21096
  ...makeComponentProps(),
20874
21097
  ...makeDensityProps(),
20875
21098
  ...makeTagProps(),
@@ -20896,7 +21119,9 @@ const VTable = genericComponent()({
20896
21119
  'v-table--fixed-footer': props.fixedFooter,
20897
21120
  'v-table--has-top': !!slots.top,
20898
21121
  'v-table--has-bottom': !!slots.bottom,
20899
- 'v-table--hover': props.hover
21122
+ 'v-table--hover': props.hover,
21123
+ 'v-table--striped-even': props.striped === 'even',
21124
+ 'v-table--striped-odd': props.striped === 'odd'
20900
21125
  }, themeClasses.value, densityClasses.value, props.class]),
20901
21126
  "style": normalizeStyle(props.style)
20902
21127
  }, {
@@ -22071,7 +22296,8 @@ const makeCalendarProps = propsFactory({
22071
22296
  firstDayOfWeek: {
22072
22297
  type: [Number, String],
22073
22298
  default: undefined
22074
- }
22299
+ },
22300
+ weekdayFormat: String
22075
22301
  }, 'calendar');
22076
22302
  function useCalendar(props) {
22077
22303
  const adapter = useDate();
@@ -22312,7 +22538,7 @@ const VDatePickerMonth = genericComponent()({
22312
22538
  "ref": daysRef,
22313
22539
  "key": daysInMonth.value[0].date?.toString(),
22314
22540
  "class": "v-date-picker-month__days"
22315
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => createElementVNode("div", {
22541
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => createElementVNode("div", {
22316
22542
  "class": normalizeClass(['v-date-picker-month__day', 'v-date-picker-month__weekday'])
22317
22543
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22318
22544
  const slotProps = {
@@ -22821,7 +23047,9 @@ const VDatePicker = genericComponent()({
22821
23047
  "max": maxDate.value,
22822
23048
  "year": year.value,
22823
23049
  "allowedMonths": allowedMonths
22824
- }), null) : viewMode.value === 'year' ? createVNode(VDatePickerYears, mergeProps({
23050
+ }), {
23051
+ ...pick(slots, ['month'])
23052
+ }) : viewMode.value === 'year' ? createVNode(VDatePickerYears, mergeProps({
22825
23053
  "key": "date-picker-years"
22826
23054
  }, datePickerYearsProps, {
22827
23055
  "modelValue": year.value,
@@ -22829,7 +23057,9 @@ const VDatePicker = genericComponent()({
22829
23057
  "min": minDate.value,
22830
23058
  "max": maxDate.value,
22831
23059
  "allowedYears": allowedYears
22832
- }), null) : createVNode(VDatePickerMonth, mergeProps({
23060
+ }), {
23061
+ ...pick(slots, ['year'])
23062
+ }) : createVNode(VDatePickerMonth, mergeProps({
22833
23063
  "key": "date-picker-month"
22834
23064
  }, datePickerMonthProps, {
22835
23065
  "modelValue": model.value,
@@ -22840,7 +23070,9 @@ const VDatePicker = genericComponent()({
22840
23070
  "onUpdate:year": [$event => year.value = $event, onUpdateYear],
22841
23071
  "min": minDate.value,
22842
23072
  "max": maxDate.value
22843
- }), null)]
23073
+ }), {
23074
+ ...pick(slots, ['day'])
23075
+ })]
22844
23076
  })]),
22845
23077
  actions: slots.actions
22846
23078
  });
@@ -23931,6 +24163,9 @@ const VInfiniteScroll = genericComponent()({
23931
24163
  startStatus.value = status;
23932
24164
  } else if (side === 'end') {
23933
24165
  endStatus.value = status;
24166
+ } else if (side === 'both') {
24167
+ startStatus.value = status;
24168
+ endStatus.value = status;
23934
24169
  }
23935
24170
  }
23936
24171
  function getStatus(side) {
@@ -24042,6 +24277,32 @@ const VInfiniteScroll = genericComponent()({
24042
24277
  }, [renderSide('end', endStatus.value)])]
24043
24278
  });
24044
24279
  });
24280
+ function reset(side) {
24281
+ const effectiveSide = side ?? props.side;
24282
+ setStatus(effectiveSide, 'ok');
24283
+ nextTick(() => {
24284
+ setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
24285
+ if (props.mode !== 'manual') {
24286
+ nextTick(() => {
24287
+ window.requestAnimationFrame(() => {
24288
+ window.requestAnimationFrame(() => {
24289
+ window.requestAnimationFrame(() => {
24290
+ if (effectiveSide === 'both') {
24291
+ intersecting('start');
24292
+ intersecting('end');
24293
+ } else {
24294
+ intersecting(effectiveSide);
24295
+ }
24296
+ });
24297
+ });
24298
+ });
24299
+ });
24300
+ }
24301
+ });
24302
+ }
24303
+ return {
24304
+ reset
24305
+ };
24045
24306
  }
24046
24307
  });
24047
24308
 
@@ -24121,8 +24382,47 @@ const VItem = genericComponent()({
24121
24382
  }
24122
24383
  });
24123
24384
 
24124
- // Styles
24125
- const VKbd = createSimpleFunctional('v-kbd', 'kbd');
24385
+ const makeVKbdProps = propsFactory({
24386
+ ...makeBorderProps(),
24387
+ ...makeComponentProps(),
24388
+ ...makeRoundedProps(),
24389
+ ...makeTagProps({
24390
+ tag: 'kbd'
24391
+ }),
24392
+ ...makeThemeProps(),
24393
+ ...makeElevationProps(),
24394
+ color: String
24395
+ }, 'VKbd');
24396
+ const VKbd = genericComponent()({
24397
+ name: 'VKbd',
24398
+ props: makeVKbdProps(),
24399
+ setup(props, _ref) {
24400
+ let {
24401
+ slots
24402
+ } = _ref;
24403
+ const {
24404
+ themeClasses
24405
+ } = provideTheme(props);
24406
+ const {
24407
+ borderClasses
24408
+ } = useBorder(props);
24409
+ const {
24410
+ roundedClasses
24411
+ } = useRounded(props);
24412
+ const {
24413
+ backgroundColorClasses,
24414
+ backgroundColorStyles
24415
+ } = useBackgroundColor(() => props.color);
24416
+ const {
24417
+ elevationClasses
24418
+ } = useElevation(props);
24419
+ useRender(() => createVNode(props.tag, {
24420
+ "class": normalizeClass(['v-kbd', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
24421
+ "style": normalizeStyle([backgroundColorStyles.value, props.style])
24422
+ }, slots));
24423
+ return {};
24424
+ }
24425
+ });
24126
24426
 
24127
24427
  const makeVLayoutProps = propsFactory({
24128
24428
  ...makeComponentProps(),
@@ -24960,6 +25260,14 @@ const makeVNumberInputProps = propsFactory({
24960
25260
  type: Number,
24961
25261
  default: 0
24962
25262
  },
25263
+ minFractionDigits: {
25264
+ type: Number,
25265
+ default: null
25266
+ },
25267
+ decimalSeparator: {
25268
+ type: String,
25269
+ validator: v => !v || v.length === 1
25270
+ },
24963
25271
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24964
25272
  }, 'VNumberInput');
24965
25273
  const VNumberInput = genericComponent()({
@@ -24985,11 +25293,24 @@ const VNumberInput = genericComponent()({
24985
25293
  const form = useForm(props);
24986
25294
  const controlsDisabled = computed(() => form.isDisabled.value || form.isReadonly.value);
24987
25295
  const isFocused = shallowRef(props.focused);
25296
+ const {
25297
+ decimalSeparator: decimalSeparatorFromLocale
25298
+ } = useLocale();
25299
+ const decimalSeparator = computed(() => props.decimalSeparator?.[0] || decimalSeparatorFromLocale.value);
24988
25300
  function correctPrecision(val) {
24989
25301
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
25302
+ let trim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
24990
25303
  const fixed = precision == null ? String(val) : val.toFixed(precision);
24991
- return isFocused.value ? Number(fixed).toString() // trim zeros
24992
- : fixed;
25304
+ if (isFocused.value && trim) {
25305
+ return Number(fixed).toString() // trim zeros
25306
+ .replace('.', decimalSeparator.value);
25307
+ }
25308
+ if (props.minFractionDigits === null || precision !== null && precision < props.minFractionDigits) {
25309
+ return fixed.replace('.', decimalSeparator.value);
25310
+ }
25311
+ let [baseDigits, fractionDigits] = fixed.split('.');
25312
+ fractionDigits = (fractionDigits ?? '').padEnd(props.minFractionDigits, '0').replace(new RegExp(`(?<=\\d{${props.minFractionDigits}})0`, 'g'), '');
25313
+ return [baseDigits, fractionDigits].filter(Boolean).join(decimalSeparator.value);
24993
25314
  }
24994
25315
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24995
25316
  const _inputText = shallowRef(null);
@@ -25006,8 +25327,11 @@ const VNumberInput = genericComponent()({
25006
25327
  if (val === null || val === '') {
25007
25328
  model.value = null;
25008
25329
  _inputText.value = null;
25009
- } else if (!isNaN(Number(val)) && Number(val) <= props.max && Number(val) >= props.min) {
25010
- model.value = Number(val);
25330
+ return;
25331
+ }
25332
+ const parsedValue = Number(val.replace(decimalSeparator.value, '.'));
25333
+ if (!isNaN(parsedValue) && parsedValue <= props.max && parsedValue >= props.min) {
25334
+ model.value = parsedValue;
25011
25335
  _inputText.value = val;
25012
25336
  }
25013
25337
  }
@@ -25044,6 +25368,7 @@ const VNumberInput = genericComponent()({
25044
25368
  }
25045
25369
  };
25046
25370
  watch(() => props.precision, () => formatInputValue());
25371
+ watch(() => props.minFractionDigits, () => formatInputValue());
25047
25372
  onMounted(() => {
25048
25373
  clampModel();
25049
25374
  });
@@ -25077,24 +25402,24 @@ const VNumberInput = genericComponent()({
25077
25402
  selectionEnd
25078
25403
  } = inputElement ?? {};
25079
25404
  const potentialNewInputVal = existingTxt ? existingTxt.slice(0, selectionStart) + e.data + existingTxt.slice(selectionEnd) : e.data;
25080
- const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision);
25405
+ const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision, decimalSeparator.value);
25081
25406
 
25082
- // Only numbers, "-", "." are allowed
25083
- // AND "-", "." are allowed only once
25084
- // AND "-" is only allowed at the start
25085
- if (!/^-?(\d+(\.\d*)?|(\.\d+)|\d*|\.)$/.test(potentialNewInputVal)) {
25407
+ // Allow only numbers, "-" and {decimal separator}
25408
+ // Allow "-" and {decimal separator} only once
25409
+ // Allow "-" only at the start
25410
+ if (!new RegExp(`^-?\\d*${escapeForRegex(decimalSeparator.value)}?\\d*$`).test(potentialNewInputVal)) {
25086
25411
  e.preventDefault();
25087
25412
  inputElement.value = potentialNewNumber;
25088
25413
  }
25089
25414
  if (props.precision == null) return;
25090
25415
 
25091
25416
  // Ignore decimal digits above precision limit
25092
- if (potentialNewInputVal.split('.')[1]?.length > props.precision) {
25417
+ if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {
25093
25418
  e.preventDefault();
25094
25419
  inputElement.value = potentialNewNumber;
25095
25420
  }
25096
25421
  // Ignore decimal separator when precision = 0
25097
- if (props.precision === 0 && potentialNewInputVal.includes('.')) {
25422
+ if (props.precision === 0 && potentialNewInputVal.includes(decimalSeparator.value)) {
25098
25423
  e.preventDefault();
25099
25424
  inputElement.value = potentialNewNumber;
25100
25425
  }
@@ -25146,19 +25471,16 @@ const VNumberInput = genericComponent()({
25146
25471
  if (controlsDisabled.value) return;
25147
25472
  if (!vTextFieldRef.value) return;
25148
25473
  const actualText = vTextFieldRef.value.value;
25149
- if (actualText && !isNaN(Number(actualText))) {
25150
- inputText.value = correctPrecision(clamp(Number(actualText), props.min, props.max));
25474
+ const parsedValue = Number(actualText.replace(decimalSeparator.value, '.'));
25475
+ if (actualText && !isNaN(parsedValue)) {
25476
+ inputText.value = correctPrecision(clamp(parsedValue, props.min, props.max));
25151
25477
  } else {
25152
25478
  inputText.value = null;
25153
25479
  }
25154
25480
  }
25155
25481
  function formatInputValue() {
25156
25482
  if (controlsDisabled.value) return;
25157
- if (model.value === null || isNaN(model.value)) {
25158
- inputText.value = null;
25159
- return;
25160
- }
25161
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25483
+ inputText.value = model.value !== null && !isNaN(model.value) ? correctPrecision(model.value, props.precision, false) : null;
25162
25484
  }
25163
25485
  function trimDecimalZeros() {
25164
25486
  if (controlsDisabled.value) return;
@@ -25166,7 +25488,7 @@ const VNumberInput = genericComponent()({
25166
25488
  inputText.value = null;
25167
25489
  return;
25168
25490
  }
25169
- inputText.value = model.value.toString();
25491
+ inputText.value = model.value.toString().replace('.', decimalSeparator.value);
25170
25492
  }
25171
25493
  function onFocus() {
25172
25494
  trimDecimalZeros();
@@ -25368,6 +25690,21 @@ const VOtpInput = genericComponent()({
25368
25690
  const contentRef = ref();
25369
25691
  const inputRef = ref([]);
25370
25692
  const current = computed(() => inputRef.value[focusIndex.value]);
25693
+ const intersectScope = effectScope();
25694
+ intersectScope.run(() => {
25695
+ const {
25696
+ intersectionRef,
25697
+ isIntersecting
25698
+ } = useIntersectionObserver();
25699
+ watch(isIntersecting, v => {
25700
+ if (!v) return;
25701
+ intersectionRef.value?.focus();
25702
+ intersectScope.stop();
25703
+ });
25704
+ watchEffect(() => {
25705
+ intersectionRef.value = inputRef.value[0];
25706
+ });
25707
+ });
25371
25708
  function onInput() {
25372
25709
  // The maxlength attribute doesn't work for the number type input, so the text type is used.
25373
25710
  // The following logic simulates the behavior of a number input.
@@ -25418,9 +25755,10 @@ const VOtpInput = genericComponent()({
25418
25755
  e.preventDefault();
25419
25756
  e.stopPropagation();
25420
25757
  const clipboardText = e?.clipboardData?.getData('Text').trim().slice(0, length.value) ?? '';
25758
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25421
25759
  if (isValidNumber(clipboardText)) return;
25422
25760
  model.value = clipboardText.split('');
25423
- inputRef.value?.[index].blur();
25761
+ inputRef.value?.[finalIndex].focus();
25424
25762
  }
25425
25763
  function reset() {
25426
25764
  model.value = [];
@@ -28114,6 +28452,9 @@ const VTextarea = genericComponent()({
28114
28452
  focus,
28115
28453
  blur
28116
28454
  } = useFocus(props);
28455
+ const {
28456
+ onIntersect
28457
+ } = useAutofocus(props);
28117
28458
  const counterValue = computed(() => {
28118
28459
  return typeof props.counterValue === 'function' ? props.counterValue(model.value) : (model.value || '').toString().length;
28119
28460
  });
@@ -28122,10 +28463,6 @@ const VTextarea = genericComponent()({
28122
28463
  if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
28123
28464
  return props.counter;
28124
28465
  });
28125
- function onIntersect(isIntersecting, entries) {
28126
- if (!props.autofocus || !isIntersecting) return;
28127
- entries[0].target?.focus?.();
28128
- }
28129
28466
  const vInputRef = ref();
28130
28467
  const vFieldRef = ref();
28131
28468
  const controlHeight = shallowRef('');
@@ -30121,11 +30458,6 @@ const makeVIconBtnProps = propsFactory({
30121
30458
  hideOverlay: Boolean,
30122
30459
  icon: [String, Function, Object],
30123
30460
  iconColor: String,
30124
- iconSize: [Number, String],
30125
- iconSizes: {
30126
- type: Array,
30127
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
30128
- },
30129
30461
  loading: Boolean,
30130
30462
  opacity: [Number, String],
30131
30463
  readonly: Boolean,
@@ -30145,6 +30477,7 @@ const makeVIconBtnProps = propsFactory({
30145
30477
  ...makeBorderProps(),
30146
30478
  ...makeComponentProps(),
30147
30479
  ...makeElevationProps(),
30480
+ ...makeIconSizeProps(),
30148
30481
  ...makeRoundedProps(),
30149
30482
  ...makeTagProps({
30150
30483
  tag: 'button'
@@ -30199,7 +30532,6 @@ const VIconBtn = genericComponent()({
30199
30532
  })()
30200
30533
  }));
30201
30534
  const btnSizeMap = new Map(props.sizes);
30202
- const iconSizeMap = new Map(props.iconSizes);
30203
30535
  function onClick() {
30204
30536
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
30205
30537
  isActive.value = !isActive.value;
@@ -30211,12 +30543,12 @@ const VIconBtn = genericComponent()({
30211
30543
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
30212
30544
  const btnHeight = props.height ?? btnSize;
30213
30545
  const btnWidth = props.width ?? btnSize;
30214
- const _iconSize = props.iconSize;
30215
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
30216
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30546
+ const {
30547
+ iconSize
30548
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
30217
30549
  const iconProps = {
30218
30550
  icon,
30219
- size: iconSize,
30551
+ size: iconSize.value,
30220
30552
  iconColor: props.iconColor,
30221
30553
  opacity: props.opacity
30222
30554
  };
@@ -30259,7 +30591,7 @@ const VIconBtn = genericComponent()({
30259
30591
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30260
30592
  "indeterminate": "disable-shrink",
30261
30593
  "width": "2",
30262
- "size": iconSize
30594
+ "size": iconSize.value
30263
30595
  }, null)])]
30264
30596
  });
30265
30597
  });
@@ -30267,6 +30599,251 @@ const VIconBtn = genericComponent()({
30267
30599
  }
30268
30600
  });
30269
30601
 
30602
+ // Utilities
30603
+
30604
+ // Types
30605
+
30606
+ const makeMaskProps = propsFactory({
30607
+ mask: [String, Object],
30608
+ returnMaskedValue: Boolean
30609
+ }, 'mask');
30610
+ const defaultDelimiters = /[-!$%^&*()_+|~=`{}[\]:";'<>?,./\\ ]/;
30611
+ const presets = {
30612
+ 'credit-card': '#### - #### - #### - ####',
30613
+ date: '##/##/####',
30614
+ 'date-time': '##/##/#### ##:##',
30615
+ 'iso-date': '####-##-##',
30616
+ 'iso-date-time': '####-##-## ##:##',
30617
+ phone: '(###) ### - ####',
30618
+ social: '###-##-####',
30619
+ time: '##:##',
30620
+ 'time-with-seconds': '##:##:##'
30621
+ };
30622
+ function isMaskDelimiter(char) {
30623
+ return char ? defaultDelimiters.test(char) : false;
30624
+ }
30625
+ const defaultTokens = {
30626
+ '#': {
30627
+ pattern: /[0-9]/
30628
+ },
30629
+ A: {
30630
+ pattern: /[A-Z]/i,
30631
+ convert: v => v.toUpperCase()
30632
+ },
30633
+ a: {
30634
+ pattern: /[a-z]/i,
30635
+ convert: v => v.toLowerCase()
30636
+ },
30637
+ N: {
30638
+ pattern: /[0-9A-Z]/i,
30639
+ convert: v => v.toUpperCase()
30640
+ },
30641
+ n: {
30642
+ pattern: /[0-9a-z]/i,
30643
+ convert: v => v.toLowerCase()
30644
+ },
30645
+ X: {
30646
+ pattern: defaultDelimiters
30647
+ }
30648
+ };
30649
+ function useMask(props, inputRef) {
30650
+ const mask = computed(() => {
30651
+ if (typeof props.mask === 'string') {
30652
+ if (props.mask in presets) return presets[props.mask];
30653
+ return props.mask;
30654
+ }
30655
+ return props.mask?.mask ?? '';
30656
+ });
30657
+ const tokens = computed(() => {
30658
+ return {
30659
+ ...defaultTokens,
30660
+ ...(isObject(props.mask) ? props.mask.tokens : null)
30661
+ };
30662
+ });
30663
+ const selection = shallowRef(0);
30664
+ const lazySelection = shallowRef(0);
30665
+ function isMask(char) {
30666
+ return char in tokens.value;
30667
+ }
30668
+ function maskValidates(mask, char) {
30669
+ if (char == null || !isMask(mask)) return false;
30670
+ const item = tokens.value[mask];
30671
+ if (item.pattern) return item.pattern.test(char);
30672
+ return item.test(char);
30673
+ }
30674
+ function convert(mask, char) {
30675
+ const item = tokens.value[mask];
30676
+ return item.convert ? item.convert(char) : char;
30677
+ }
30678
+ function maskText(text) {
30679
+ const trimmedText = text?.trim().replace(/\s+/g, ' ');
30680
+ if (trimmedText == null) return '';
30681
+ if (!mask.value.length || !trimmedText.length) return trimmedText;
30682
+ let textIndex = 0;
30683
+ let maskIndex = 0;
30684
+ let newText = '';
30685
+ while (maskIndex < mask.value.length) {
30686
+ const mchar = mask.value[maskIndex];
30687
+ const tchar = trimmedText[textIndex];
30688
+
30689
+ // Escaped character in mask, the next mask character is inserted
30690
+ if (mchar === '\\') {
30691
+ newText += mask.value[maskIndex + 1];
30692
+ maskIndex += 2;
30693
+ continue;
30694
+ }
30695
+ if (!isMask(mchar)) {
30696
+ newText += mchar;
30697
+ if (tchar === mchar) {
30698
+ textIndex++;
30699
+ }
30700
+ } else if (maskValidates(mchar, tchar)) {
30701
+ newText += convert(mchar, tchar);
30702
+ textIndex++;
30703
+ } else {
30704
+ break;
30705
+ }
30706
+ maskIndex++;
30707
+ }
30708
+ return newText;
30709
+ }
30710
+ function unmaskText(text) {
30711
+ if (text == null) return null;
30712
+ if (!mask.value.length || !text.length) return text;
30713
+ let textIndex = 0;
30714
+ let maskIndex = 0;
30715
+ let newText = '';
30716
+ while (true) {
30717
+ const mchar = mask.value[maskIndex];
30718
+ const tchar = text[textIndex];
30719
+ if (tchar == null) break;
30720
+ if (mchar == null) {
30721
+ newText += tchar;
30722
+ textIndex++;
30723
+ continue;
30724
+ }
30725
+
30726
+ // Escaped character in mask, skip the next input character
30727
+ if (mchar === '\\') {
30728
+ if (tchar === mask.value[maskIndex + 1]) {
30729
+ textIndex++;
30730
+ }
30731
+ maskIndex += 2;
30732
+ continue;
30733
+ }
30734
+ if (maskValidates(mchar, tchar)) {
30735
+ // masked char
30736
+ newText += tchar;
30737
+ textIndex++;
30738
+ maskIndex++;
30739
+ continue;
30740
+ } else if (mchar !== tchar) {
30741
+ // input doesn't match mask, skip forward until it does
30742
+ while (true) {
30743
+ const mchar = mask.value[maskIndex++];
30744
+ if (mchar == null || maskValidates(mchar, tchar)) break;
30745
+ }
30746
+ continue;
30747
+ }
30748
+ textIndex++;
30749
+ maskIndex++;
30750
+ }
30751
+ return newText;
30752
+ }
30753
+ function setCaretPosition(newSelection) {
30754
+ selection.value = newSelection;
30755
+ inputRef.value && inputRef.value.setSelectionRange(selection.value, selection.value);
30756
+ }
30757
+ function resetSelections() {
30758
+ if (!inputRef.value?.selectionEnd) return;
30759
+ selection.value = inputRef.value.selectionEnd;
30760
+ lazySelection.value = 0;
30761
+ for (let index = 0; index < selection.value; index++) {
30762
+ isMaskDelimiter(inputRef.value.value[index]) || lazySelection.value++;
30763
+ }
30764
+ }
30765
+ function updateRange() {
30766
+ if (!inputRef.value) return;
30767
+ resetSelections();
30768
+ let selection = 0;
30769
+ const newValue = inputRef.value.value;
30770
+ if (newValue) {
30771
+ for (let index = 0; index < newValue.length; index++) {
30772
+ if (lazySelection.value <= 0) break;
30773
+ isMaskDelimiter(newValue[index]) || lazySelection.value--;
30774
+ selection++;
30775
+ }
30776
+ }
30777
+ setCaretPosition(selection);
30778
+ }
30779
+ return {
30780
+ updateRange,
30781
+ maskText,
30782
+ unmaskText
30783
+ };
30784
+ }
30785
+
30786
+ // Types
30787
+
30788
+ const makeVMaskInputProps = propsFactory({
30789
+ ...makeVTextFieldProps(),
30790
+ ...makeMaskProps()
30791
+ }, 'VMaskInput');
30792
+ const VMaskInput = genericComponent()({
30793
+ name: 'VMaskInput',
30794
+ props: makeVMaskInputProps(),
30795
+ emits: {
30796
+ 'update:modelValue': val => true
30797
+ },
30798
+ setup(props, _ref) {
30799
+ let {
30800
+ slots,
30801
+ emit
30802
+ } = _ref;
30803
+ const vTextFieldRef = ref();
30804
+ const {
30805
+ maskText,
30806
+ updateRange,
30807
+ unmaskText
30808
+ } = useMask(props, vTextFieldRef);
30809
+ const returnMaskedValue = computed(() => props.mask && props.returnMaskedValue);
30810
+ const model = useProxiedModel(props, 'modelValue', undefined,
30811
+ // Always display masked value in input when mask is applied
30812
+ val => props.mask ? maskText(unmaskText(val)) : val, val => {
30813
+ if (props.mask) {
30814
+ const valueBeforeChange = unmaskText(model.value);
30815
+ // E.g. mask is #-# and the input value is '2-23'
30816
+ // model-value should be enforced to '2-2'
30817
+ const enforcedMaskedValue = maskText(unmaskText(val));
30818
+ const newUnmaskedValue = unmaskText(enforcedMaskedValue);
30819
+ if (newUnmaskedValue === valueBeforeChange) {
30820
+ vTextFieldRef.value.value = enforcedMaskedValue;
30821
+ }
30822
+ val = newUnmaskedValue;
30823
+ updateRange();
30824
+ return returnMaskedValue.value ? maskText(val) : val;
30825
+ }
30826
+ return val;
30827
+ });
30828
+ onBeforeMount(() => {
30829
+ if (props.returnMaskedValue) {
30830
+ emit('update:modelValue', model.value);
30831
+ }
30832
+ });
30833
+ useRender(() => {
30834
+ const textFieldProps = VTextField.filterProps(props);
30835
+ return createVNode(VTextField, mergeProps(textFieldProps, {
30836
+ "modelValue": model.value,
30837
+ "onUpdate:modelValue": $event => model.value = $event,
30838
+ "ref": vTextFieldRef
30839
+ }), {
30840
+ ...slots
30841
+ });
30842
+ });
30843
+ return forwardRefs({}, vTextFieldRef);
30844
+ }
30845
+ });
30846
+
30270
30847
  // Types
30271
30848
 
30272
30849
  const makeVStepperVerticalActionsProps = propsFactory({
@@ -31338,6 +31915,7 @@ const VTreeviewItem = genericComponent()({
31338
31915
  }
31339
31916
  function onClickAction(e) {
31340
31917
  e.preventDefault();
31918
+ e.stopPropagation();
31341
31919
  emit('toggleExpand', e);
31342
31920
  }
31343
31921
  useRender(() => {
@@ -31408,6 +31986,11 @@ const makeVTreeviewChildrenProps = propsFactory({
31408
31986
  selectable: Boolean,
31409
31987
  selectedColor: String,
31410
31988
  selectStrategy: [String, Function, Object],
31989
+ index: Number,
31990
+ path: {
31991
+ type: Array,
31992
+ default: () => []
31993
+ },
31411
31994
  ...makeDensityProps()
31412
31995
  }, 'VTreeviewChildren');
31413
31996
  const VTreeviewChildren = genericComponent()({
@@ -31435,12 +32018,19 @@ const VTreeviewChildren = genericComponent()({
31435
32018
  select(!isSelected);
31436
32019
  }
31437
32020
  }
31438
- return () => slots.default?.() ?? props.items?.map(item => {
32021
+ return () => slots.default?.() ?? props.items?.map((item, index) => {
31439
32022
  const {
31440
32023
  children,
31441
32024
  props: itemProps
31442
32025
  } = item;
31443
32026
  const loading = isLoading.has(item.value);
32027
+ const treeItemProps = {
32028
+ index,
32029
+ depth: props.path?.length ?? 0,
32030
+ isFirst: index === 0,
32031
+ isLast: props.items ? props.items.length - 1 === index : false,
32032
+ path: [...props.path, index]
32033
+ };
31444
32034
  const slotsWithItem = {
31445
32035
  prepend: slotProps => createElementVNode(Fragment, null, [props.selectable && (!children || children && !['leaf', 'single-leaf'].includes(props.selectStrategy)) && createElementVNode("div", null, [createVNode(VCheckboxBtn, {
31446
32036
  "key": item.value,
@@ -31461,11 +32051,13 @@ const VTreeviewChildren = genericComponent()({
31461
32051
  }
31462
32052
  }, null)]), slots.prepend?.({
31463
32053
  ...slotProps,
32054
+ ...treeItemProps,
31464
32055
  item: item.raw,
31465
32056
  internalItem: item
31466
32057
  })]),
31467
32058
  append: slots.append ? slotProps => slots.append?.({
31468
32059
  ...slotProps,
32060
+ ...treeItemProps,
31469
32061
  item: item.raw,
31470
32062
  internalItem: item
31471
32063
  }) : undefined,
@@ -31481,9 +32073,13 @@ const VTreeviewChildren = genericComponent()({
31481
32073
  }) : undefined
31482
32074
  };
31483
32075
  const treeviewGroupProps = VTreeviewGroup.filterProps(itemProps);
31484
- const treeviewChildrenProps = VTreeviewChildren.filterProps(props);
32076
+ const treeviewChildrenProps = VTreeviewChildren.filterProps({
32077
+ ...props,
32078
+ ...treeItemProps
32079
+ });
31485
32080
  return children ? createVNode(VTreeviewGroup, mergeProps(treeviewGroupProps, {
31486
- "value": props.returnObject ? item.raw : treeviewGroupProps?.value
32081
+ "value": props.returnObject ? item.raw : treeviewGroupProps?.value,
32082
+ "rawId": treeviewGroupProps?.value
31487
32083
  }), {
31488
32084
  activator: _ref2 => {
31489
32085
  let {
@@ -31531,7 +32127,7 @@ const makeVTreeviewProps = propsFactory({
31531
32127
  ...makeFilterProps({
31532
32128
  filterKeys: ['title']
31533
32129
  }),
31534
- ...makeVTreeviewChildrenProps(),
32130
+ ...omit(makeVTreeviewChildrenProps(), ['index', 'path']),
31535
32131
  ...omit(makeVListProps({
31536
32132
  collapseIcon: '$treeviewCollapse',
31537
32133
  expandIcon: '$treeviewExpand',
@@ -31774,6 +32370,7 @@ var components = /*#__PURE__*/Object.freeze({
31774
32370
  VListSubheader: VListSubheader,
31775
32371
  VLocaleProvider: VLocaleProvider,
31776
32372
  VMain: VMain,
32373
+ VMaskInput: VMaskInput,
31777
32374
  VMenu: VMenu,
31778
32375
  VMessages: VMessages,
31779
32376
  VNavigationDrawer: VNavigationDrawer,
@@ -32171,7 +32768,7 @@ function createVuetify$1() {
32171
32768
  };
32172
32769
  });
32173
32770
  }
32174
- const version$1 = "3.8.9-master.2025-06-14";
32771
+ const version$1 = "3.8.10-dev.2025-06-18";
32175
32772
  createVuetify$1.version = version$1;
32176
32773
 
32177
32774
  // Vue's inject() can only be used in setup
@@ -32469,7 +33066,7 @@ var index = /*#__PURE__*/Object.freeze({
32469
33066
 
32470
33067
  /* eslint-disable local-rules/sort-imports */
32471
33068
 
32472
- const version = "3.8.9-master.2025-06-14";
33069
+ const version = "3.8.10-dev.2025-06-18";
32473
33070
 
32474
33071
  /* eslint-disable local-rules/sort-imports */
32475
33072