@vuetify/nightly 3.8.6-master.2025-05-26 → 3.8.7-dev.2025-05-30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +25 -20
  2. package/dist/json/attributes.json +3672 -3588
  3. package/dist/json/importMap-labs.json +28 -28
  4. package/dist/json/importMap.json +164 -164
  5. package/dist/json/tags.json +21 -0
  6. package/dist/json/web-types.json +6618 -6326
  7. package/dist/vuetify-labs.cjs +338 -140
  8. package/dist/vuetify-labs.css +4581 -4553
  9. package/dist/vuetify-labs.d.ts +1533 -1116
  10. package/dist/vuetify-labs.esm.js +339 -141
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +338 -140
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +332 -129
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +3805 -3777
  17. package/dist/vuetify.d.ts +1022 -645
  18. package/dist/vuetify.esm.js +333 -130
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +332 -129
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1200 -1185
  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/VAppBarNavIcon.d.ts +20 -10
  31. package/lib/components/VAutocomplete/VAutocomplete.d.ts +154 -103
  32. package/lib/components/VAutocomplete/VAutocomplete.js +21 -3
  33. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  34. package/lib/components/VBtn/VBtn.d.ts +20 -10
  35. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  36. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  37. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  38. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  39. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  40. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  41. package/lib/components/VCard/VCard.d.ts +20 -10
  42. package/lib/components/VCheckbox/VCheckbox.d.ts +23 -13
  43. package/lib/components/VCheckbox/VCheckboxBtn.d.ts +20 -10
  44. package/lib/components/VChip/VChip.d.ts +20 -10
  45. package/lib/components/VChipGroup/VChipGroup.d.ts +10 -0
  46. package/lib/components/VCombobox/VCombobox.d.ts +154 -103
  47. package/lib/components/VCombobox/VCombobox.js +22 -3
  48. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  49. package/lib/components/VDataTable/VDataTable.d.ts +18 -0
  50. package/lib/components/VDataTable/VDataTableHeaders.d.ts +13 -0
  51. package/lib/components/VDataTable/VDataTableHeaders.js +4 -2
  52. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  53. package/lib/components/VDataTable/VDataTableServer.d.ts +13 -0
  54. package/lib/components/VDataTable/VDataTableVirtual.d.ts +13 -0
  55. package/lib/components/VDatePicker/VDatePicker.d.ts +10 -0
  56. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +10 -0
  57. package/lib/components/VDatePicker/VDatePickerMonth.js +1 -1
  58. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  59. package/lib/components/VExpansionPanel/VExpansionPanel.d.ts +20 -10
  60. package/lib/components/VExpansionPanel/VExpansionPanelTitle.d.ts +20 -10
  61. package/lib/components/VExpansionPanel/VExpansionPanels.d.ts +20 -10
  62. package/lib/components/VFab/VFab.d.ts +20 -10
  63. package/lib/components/VField/VField.d.ts +3 -3
  64. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  65. package/lib/components/VInput/VInput.d.ts +4 -4
  66. package/lib/components/VList/VList.d.ts +13 -0
  67. package/lib/components/VList/VList.js +4 -1
  68. package/lib/components/VList/VList.js.map +1 -1
  69. package/lib/components/VList/VListChildren.js.map +1 -1
  70. package/lib/components/VList/VListItem.d.ts +23 -10
  71. package/lib/components/VList/VListItem.js +7 -3
  72. package/lib/components/VList/VListItem.js.map +1 -1
  73. package/lib/components/VList/list.d.ts +9 -2
  74. package/lib/components/VList/list.js +7 -0
  75. package/lib/components/VList/list.js.map +1 -1
  76. package/lib/components/VNumberInput/VNumberInput.d.ts +103 -89
  77. package/lib/components/VNumberInput/VNumberInput.js +19 -4
  78. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  79. package/lib/components/VOtpInput/VOtpInput.js +2 -1
  80. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  81. package/lib/components/VOverlay/VOverlay.css +1 -1
  82. package/lib/components/VOverlay/_variables.scss +1 -1
  83. package/lib/components/VRadio/VRadio.d.ts +20 -10
  84. package/lib/components/VRadioGroup/VRadioGroup.d.ts +23 -13
  85. package/lib/components/VRangeSlider/VRangeSlider.d.ts +3 -3
  86. package/lib/components/VSelect/VSelect.d.ts +171 -107
  87. package/lib/components/VSelect/VSelect.js +21 -3
  88. package/lib/components/VSelect/VSelect.js.map +1 -1
  89. package/lib/components/VSelectionControl/VSelectionControl.d.ts +20 -10
  90. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.d.ts +28 -14
  91. package/lib/components/VSlideGroup/VSlideGroup.d.ts +10 -0
  92. package/lib/components/VSlideGroup/VSlideGroup.js +2 -1
  93. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  94. package/lib/components/VSlider/VSlider.d.ts +3 -3
  95. package/lib/components/VSlider/VSliderThumb.d.ts +20 -10
  96. package/lib/components/VStepper/VStepperItem.d.ts +28 -14
  97. package/lib/components/VSwitch/VSwitch.d.ts +23 -13
  98. package/lib/components/VTabs/VTab.d.ts +56 -28
  99. package/lib/components/VTabs/VTabs.d.ts +10 -0
  100. package/lib/components/VTextField/VTextField.d.ts +27 -27
  101. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  102. package/lib/composables/calendar.d.ts +6 -0
  103. package/lib/composables/calendar.js +2 -1
  104. package/lib/composables/calendar.js.map +1 -1
  105. package/lib/composables/date/DateAdapter.d.ts +1 -1
  106. package/lib/composables/date/DateAdapter.js.map +1 -1
  107. package/lib/composables/date/adapters/vuetify.d.ts +1 -1
  108. package/lib/composables/date/adapters/vuetify.js +4 -4
  109. package/lib/composables/date/adapters/vuetify.js.map +1 -1
  110. package/lib/composables/date/date.d.ts +1 -1
  111. package/lib/composables/date/index.d.ts +1 -0
  112. package/lib/composables/date/index.js +1 -0
  113. package/lib/composables/date/index.js.map +1 -1
  114. package/lib/composables/filter.js +3 -0
  115. package/lib/composables/filter.js.map +1 -1
  116. package/lib/composables/iconSizes.d.ts +28 -0
  117. package/lib/composables/iconSizes.js +23 -0
  118. package/lib/composables/iconSizes.js.map +1 -0
  119. package/lib/composables/theme.d.ts +6 -1
  120. package/lib/composables/theme.js +94 -26
  121. package/lib/composables/theme.js.map +1 -1
  122. package/lib/composables/virtual.js +6 -1
  123. package/lib/composables/virtual.js.map +1 -1
  124. package/lib/directives/ripple/index.d.ts +2 -1
  125. package/lib/directives/ripple/index.js +12 -7
  126. package/lib/directives/ripple/index.js.map +1 -1
  127. package/lib/entry-bundler.d.ts +1 -1
  128. package/lib/entry-bundler.js +1 -1
  129. package/lib/entry-bundler.js.map +1 -1
  130. package/lib/framework.d.ts +64 -59
  131. package/lib/framework.js +1 -1
  132. package/lib/framework.js.map +1 -1
  133. package/lib/labs/VCalendar/VCalendar.d.ts +10 -0
  134. package/lib/labs/VColorInput/VColorInput.d.ts +3 -3
  135. package/lib/labs/VDateInput/VDateInput.d.ts +97 -87
  136. package/lib/labs/VFileUpload/VFileUpload.d.ts +3 -3
  137. package/lib/labs/VFileUpload/VFileUploadItem.d.ts +20 -10
  138. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  139. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  140. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  141. package/lib/labs/VStepperVertical/VStepperVertical.d.ts +20 -10
  142. package/lib/labs/VStepperVertical/VStepperVerticalItem.d.ts +20 -10
  143. package/lib/labs/VTreeview/VTreeview.d.ts +13 -0
  144. package/lib/labs/VTreeview/VTreeviewItem.d.ts +20 -10
  145. package/lib/labs/entry-bundler.d.ts +1 -1
  146. package/lib/util/globals.d.ts +1 -0
  147. package/lib/util/globals.js +1 -0
  148. package/lib/util/globals.js.map +1 -1
  149. package/package.json +3 -1
package/dist/vuetify.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.6-master.2025-05-26
2
+ * Vuetify v3.8.7-dev.2025-05-30
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -14,6 +14,7 @@
14
14
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
15
15
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
16
16
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
17
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
17
18
 
18
19
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
19
20
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -2828,6 +2829,7 @@
2828
2829
  function genDefaults$1() {
2829
2830
  return {
2830
2831
  defaultTheme: 'light',
2832
+ prefix: 'v-',
2831
2833
  variations: {
2832
2834
  colors: [],
2833
2835
  lighten: 0,
@@ -2909,7 +2911,10 @@
2909
2911
  }
2910
2912
  }
2911
2913
  },
2912
- stylesheetId: 'vuetify-theme-stylesheet'
2914
+ stylesheetId: 'vuetify-theme-stylesheet',
2915
+ scoped: false,
2916
+ unimportant: false,
2917
+ utilities: true
2913
2918
  };
2914
2919
  }
2915
2920
  function parseThemeOptions() {
@@ -2932,21 +2937,21 @@
2932
2937
  function createCssClass(lines, selector, content, scope) {
2933
2938
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2934
2939
  }
2935
- function genCssVariables(theme) {
2940
+ function genCssVariables(theme, prefix) {
2936
2941
  const lightOverlay = theme.dark ? 2 : 1;
2937
2942
  const darkOverlay = theme.dark ? 1 : 2;
2938
2943
  const variables = [];
2939
2944
  for (const [key, value] of Object.entries(theme.colors)) {
2940
2945
  const rgb = parseColor(value);
2941
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2946
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2942
2947
  if (!key.startsWith('on-')) {
2943
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2948
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2944
2949
  }
2945
2950
  }
2946
2951
  for (const [key, value] of Object.entries(theme.variables)) {
2947
2952
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2948
2953
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2949
- variables.push(`--v-${key}: ${rgb ?? value}`);
2954
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2950
2955
  }
2951
2956
  return variables;
2952
2957
  }
@@ -2990,7 +2995,8 @@
2990
2995
  const scopeSelector = `:where(${scope})`;
2991
2996
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2992
2997
  }
2993
- function upsertStyles(styleEl, styles) {
2998
+ function upsertStyles(id, cspNonce, styles) {
2999
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2994
3000
  if (!styleEl) return;
2995
3001
  styleEl.innerHTML = styles;
2996
3002
  }
@@ -3010,8 +3016,17 @@
3010
3016
  // Composables
3011
3017
  function createTheme(options) {
3012
3018
  const parsedOptions = parseThemeOptions(options);
3013
- const name = vue.shallowRef(parsedOptions.defaultTheme);
3019
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
3014
3020
  const themes = vue.ref(parsedOptions.themes);
3021
+ const systemName = vue.shallowRef('light');
3022
+ const name = vue.computed({
3023
+ get() {
3024
+ return _name.value === 'system' ? systemName.value : _name.value;
3025
+ },
3026
+ set(val) {
3027
+ _name.value = val;
3028
+ }
3029
+ });
3015
3030
  const computedThemes = vue.computed(() => {
3016
3031
  const acc = {};
3017
3032
  for (const [name, original] of Object.entries(themes.value)) {
@@ -3032,28 +3047,49 @@
3032
3047
  const current = vue.toRef(() => computedThemes.value[name.value]);
3033
3048
  const styles = vue.computed(() => {
3034
3049
  const lines = [];
3050
+ const important = parsedOptions.unimportant ? '' : ' !important';
3051
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
3035
3052
  if (current.value?.dark) {
3036
3053
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
3037
3054
  }
3038
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
3055
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
3039
3056
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
3040
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
3041
- }
3042
- const bgLines = [];
3043
- const fgLines = [];
3044
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
3045
- for (const key of colors) {
3046
- if (key.startsWith('on-')) {
3047
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
3048
- } else {
3049
- 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);
3050
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
3051
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
3057
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
3058
+ }
3059
+ if (parsedOptions.utilities) {
3060
+ const bgLines = [];
3061
+ const fgLines = [];
3062
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
3063
+ for (const key of colors) {
3064
+ if (key.startsWith('on-')) {
3065
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
3066
+ } else {
3067
+ 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);
3068
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
3069
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
3070
+ }
3052
3071
  }
3072
+ lines.push(...bgLines, ...fgLines);
3053
3073
  }
3054
- lines.push(...bgLines, ...fgLines);
3055
3074
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
3056
3075
  });
3076
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
3077
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
3078
+ if (SUPPORTS_MATCH_MEDIA) {
3079
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
3080
+ function updateSystemName() {
3081
+ systemName.value = media.matches ? 'dark' : 'light';
3082
+ }
3083
+ updateSystemName();
3084
+ media.addEventListener('change', updateSystemName, {
3085
+ passive: true
3086
+ });
3087
+ if (vue.getCurrentScope()) {
3088
+ vue.onScopeDispose(() => {
3089
+ media.removeEventListener('change', updateSystemName);
3090
+ });
3091
+ }
3092
+ }
3057
3093
  function install(app) {
3058
3094
  if (parsedOptions.isDisabled) return;
3059
3095
  const head = app._context.provides.usehead;
@@ -3091,22 +3127,55 @@
3091
3127
  updateStyles();
3092
3128
  }
3093
3129
  function updateStyles() {
3094
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
3130
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
3095
3131
  }
3096
3132
  }
3097
3133
  }
3098
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
3134
+ function change(themeName) {
3135
+ if (!themeNames.value.includes(themeName)) {
3136
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
3137
+ return;
3138
+ }
3139
+ name.value = themeName;
3140
+ }
3141
+ function cycle() {
3142
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
3143
+ const currentIndex = themeArray.indexOf(name.value);
3144
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
3145
+ change(themeArray[nextIndex]);
3146
+ }
3147
+ function toggle() {
3148
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
3149
+ cycle(themeArray);
3150
+ }
3151
+ const globalName = new Proxy(name, {
3152
+ get(target, prop) {
3153
+ return target[prop];
3154
+ },
3155
+ set(target, prop, val) {
3156
+ if (prop === 'value') {
3157
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
3158
+ }
3159
+ // @ts-expect-error
3160
+ target[prop] = val;
3161
+ return true;
3162
+ }
3163
+ });
3099
3164
  return {
3100
3165
  install,
3166
+ change,
3167
+ cycle,
3168
+ toggle,
3101
3169
  isDisabled: parsedOptions.isDisabled,
3102
3170
  name,
3103
3171
  themes,
3104
3172
  current,
3105
3173
  computedThemes,
3174
+ prefix: parsedOptions.prefix,
3106
3175
  themeClasses,
3107
3176
  styles,
3108
3177
  global: {
3109
- name,
3178
+ name: globalName,
3110
3179
  current
3111
3180
  }
3112
3181
  };
@@ -3117,7 +3186,7 @@
3117
3186
  if (!theme) throw new Error('Could not find Vuetify theme injection');
3118
3187
  const name = vue.toRef(() => props.theme ?? theme.name.value);
3119
3188
  const current = vue.toRef(() => theme.themes.value[name.value]);
3120
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
3189
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
3121
3190
  const newTheme = {
3122
3191
  ...theme,
3123
3192
  name,
@@ -4664,9 +4733,15 @@
4664
4733
  };
4665
4734
  }
4666
4735
 
4736
+ // Types
4737
+
4667
4738
  const makeVBtnGroupProps = propsFactory({
4668
4739
  baseColor: String,
4669
4740
  divided: Boolean,
4741
+ direction: {
4742
+ type: String,
4743
+ default: 'horizontal'
4744
+ },
4670
4745
  ...makeBorderProps(),
4671
4746
  ...makeComponentProps(),
4672
4747
  ...makeDensityProps(),
@@ -4700,7 +4775,7 @@
4700
4775
  } = useRounded(props);
4701
4776
  provideDefaults({
4702
4777
  VBtn: {
4703
- height: 'auto',
4778
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4704
4779
  baseColor: vue.toRef(() => props.baseColor),
4705
4780
  color: vue.toRef(() => props.color),
4706
4781
  density: vue.toRef(() => props.density),
@@ -4710,7 +4785,7 @@
4710
4785
  });
4711
4786
  useRender(() => {
4712
4787
  return vue.createVNode(props.tag, {
4713
- "class": vue.normalizeClass(['v-btn-group', {
4788
+ "class": vue.normalizeClass(['v-btn-group', `v-btn-group--${props.direction}`, {
4714
4789
  'v-btn-group--divided': props.divided
4715
4790
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
4716
4791
  "style": vue.normalizeStyle(props.style)
@@ -5833,8 +5908,8 @@
5833
5908
  window.clearTimeout(element._ripple.showTimer);
5834
5909
  }
5835
5910
  let keyboardRipple = false;
5836
- function keyboardRippleShow(e) {
5837
- if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
5911
+ function keyboardRippleShow(e, keys) {
5912
+ if (!keyboardRipple && keys.includes(e.keyCode)) {
5838
5913
  keyboardRipple = true;
5839
5914
  rippleShow(e);
5840
5915
  }
@@ -5862,9 +5937,12 @@
5862
5937
  el._ripple.enabled = enabled;
5863
5938
  el._ripple.centered = modifiers.center;
5864
5939
  el._ripple.circle = modifiers.circle;
5865
- if (isObject(value) && value.class) {
5866
- el._ripple.class = value.class;
5940
+ const bindingValue = isObject(value) ? value : {};
5941
+ if (bindingValue.class) {
5942
+ el._ripple.class = bindingValue.class;
5867
5943
  }
5944
+ const allowedKeys = bindingValue.keys ?? [keyCodes.enter, keyCodes.space];
5945
+ el._ripple.keyDownHandler = e => keyboardRippleShow(e, allowedKeys);
5868
5946
  if (enabled && !wasEnabled) {
5869
5947
  if (modifiers.stop) {
5870
5948
  el.addEventListener('touchstart', rippleStop, {
@@ -5886,7 +5964,7 @@
5886
5964
  el.addEventListener('mousedown', rippleShow);
5887
5965
  el.addEventListener('mouseup', rippleHide);
5888
5966
  el.addEventListener('mouseleave', rippleHide);
5889
- el.addEventListener('keydown', keyboardRippleShow);
5967
+ el.addEventListener('keydown', e => keyboardRippleShow(e, allowedKeys));
5890
5968
  el.addEventListener('keyup', keyboardRippleHide);
5891
5969
  el.addEventListener('blur', focusRippleHide);
5892
5970
 
@@ -5906,7 +5984,9 @@
5906
5984
  el.removeEventListener('touchcancel', rippleHide);
5907
5985
  el.removeEventListener('mouseup', rippleHide);
5908
5986
  el.removeEventListener('mouseleave', rippleHide);
5909
- el.removeEventListener('keydown', keyboardRippleShow);
5987
+ if (el._ripple?.keyDownHandler) {
5988
+ el.removeEventListener('keydown', el._ripple.keyDownHandler);
5989
+ }
5910
5990
  el.removeEventListener('keyup', keyboardRippleHide);
5911
5991
  el.removeEventListener('dragstart', rippleHide);
5912
5992
  el.removeEventListener('blur', focusRippleHide);
@@ -5915,8 +5995,8 @@
5915
5995
  updateRipple(el, binding, false);
5916
5996
  }
5917
5997
  function unmounted$4(el) {
5918
- delete el._ripple;
5919
5998
  removeListeners(el);
5999
+ delete el._ripple;
5920
6000
  }
5921
6001
  function updated$1(el, binding) {
5922
6002
  if (binding.value === binding.oldValue) {
@@ -6189,6 +6269,31 @@
6189
6269
  // Utilities
6190
6270
  const VAlertTitle = createSimpleFunctional('v-alert-title');
6191
6271
 
6272
+ // Utilities
6273
+
6274
+ // Types
6275
+
6276
+ // Types
6277
+
6278
+ // Composables
6279
+ const makeIconSizeProps = propsFactory({
6280
+ iconSize: [Number, String],
6281
+ iconSizes: {
6282
+ type: Array,
6283
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6284
+ }
6285
+ }, 'iconSize');
6286
+ function useIconSizes(props, fallback) {
6287
+ const iconSize = vue.computed(() => {
6288
+ const iconSizeMap = new Map(props.iconSizes);
6289
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6290
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6291
+ });
6292
+ return {
6293
+ iconSize
6294
+ };
6295
+ }
6296
+
6192
6297
  // Types
6193
6298
 
6194
6299
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -6228,6 +6333,7 @@
6228
6333
  ...makeDensityProps(),
6229
6334
  ...makeDimensionProps(),
6230
6335
  ...makeElevationProps(),
6336
+ ...makeIconSizeProps(),
6231
6337
  ...makeLocationProps(),
6232
6338
  ...makePositionProps(),
6233
6339
  ...makeRoundedProps(),
@@ -6255,6 +6361,9 @@
6255
6361
  if (!props.type) return props.icon;
6256
6362
  return props.icon ?? `$${props.type}`;
6257
6363
  });
6364
+ const {
6365
+ iconSize
6366
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
6258
6367
  const {
6259
6368
  themeClasses
6260
6369
  } = provideTheme(props);
@@ -6302,6 +6411,11 @@
6302
6411
  const hasPrepend = !!(slots.prepend || icon.value);
6303
6412
  const hasTitle = !!(slots.title || props.title);
6304
6413
  const hasClose = !!(slots.close || props.closable);
6414
+ const iconProps = {
6415
+ density: props.density,
6416
+ icon: icon.value,
6417
+ size: iconSize.value
6418
+ };
6305
6419
  return isActive.value && vue.createVNode(props.tag, {
6306
6420
  "class": vue.normalizeClass(['v-alert', props.border && {
6307
6421
  'v-alert--border': !!props.border,
@@ -6319,19 +6433,14 @@
6319
6433
  }, null), hasPrepend && vue.createElementVNode("div", {
6320
6434
  "key": "prepend",
6321
6435
  "class": "v-alert__prepend"
6322
- }, [!slots.prepend ? vue.createVNode(VIcon, {
6323
- "key": "prepend-icon",
6324
- "density": props.density,
6325
- "icon": icon.value,
6326
- "size": props.prominent ? 44 : 28
6327
- }, null) : vue.createVNode(VDefaultsProvider, {
6436
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6437
+ "key": "prepend-icon"
6438
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6328
6439
  "key": "prepend-defaults",
6329
6440
  "disabled": !icon.value,
6330
6441
  "defaults": {
6331
6442
  VIcon: {
6332
- density: props.density,
6333
- icon: icon.value,
6334
- size: props.prominent ? 44 : 28
6443
+ ...iconProps
6335
6444
  }
6336
6445
  }
6337
6446
  }, slots.prepend)]), vue.createElementVNode("div", {
@@ -7856,6 +7965,7 @@
7856
7965
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7857
7966
  const makeVSlideGroupProps = propsFactory({
7858
7967
  centerActive: Boolean,
7968
+ contentClass: null,
7859
7969
  direction: {
7860
7970
  type: String,
7861
7971
  default: 'horizontal'
@@ -8168,7 +8278,7 @@
8168
8278
  })]), vue.createElementVNode("div", {
8169
8279
  "key": "container",
8170
8280
  "ref": containerRef,
8171
- "class": "v-slide-group__container",
8281
+ "class": vue.normalizeClass(['v-slide-group__container', props.contentClass]),
8172
8282
  "onScroll": onScroll
8173
8283
  }, [vue.createElementVNode("div", {
8174
8284
  "ref": contentRef,
@@ -8530,16 +8640,85 @@
8530
8640
  }
8531
8641
  });
8532
8642
 
8643
+ const makeVDividerProps = propsFactory({
8644
+ color: String,
8645
+ inset: Boolean,
8646
+ length: [Number, String],
8647
+ opacity: [Number, String],
8648
+ thickness: [Number, String],
8649
+ vertical: Boolean,
8650
+ ...makeComponentProps(),
8651
+ ...makeThemeProps()
8652
+ }, 'VDivider');
8653
+ const VDivider = genericComponent()({
8654
+ name: 'VDivider',
8655
+ props: makeVDividerProps(),
8656
+ setup(props, _ref) {
8657
+ let {
8658
+ attrs,
8659
+ slots
8660
+ } = _ref;
8661
+ const {
8662
+ themeClasses
8663
+ } = provideTheme(props);
8664
+ const {
8665
+ textColorClasses,
8666
+ textColorStyles
8667
+ } = useTextColor(() => props.color);
8668
+ const dividerStyles = vue.computed(() => {
8669
+ const styles = {};
8670
+ if (props.length) {
8671
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8672
+ }
8673
+ if (props.thickness) {
8674
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8675
+ }
8676
+ return styles;
8677
+ });
8678
+ useRender(() => {
8679
+ const divider = vue.createElementVNode("hr", {
8680
+ "class": vue.normalizeClass([{
8681
+ 'v-divider': true,
8682
+ 'v-divider--inset': props.inset,
8683
+ 'v-divider--vertical': props.vertical
8684
+ }, themeClasses.value, textColorClasses.value, props.class]),
8685
+ "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
8686
+ '--v-border-opacity': props.opacity
8687
+ }, props.style]),
8688
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8689
+ "role": `${attrs.role || 'separator'}`
8690
+ }, null);
8691
+ if (!slots.default) return divider;
8692
+ return vue.createElementVNode("div", {
8693
+ "class": vue.normalizeClass(['v-divider__wrapper', {
8694
+ 'v-divider__wrapper--vertical': props.vertical,
8695
+ 'v-divider__wrapper--inset': props.inset
8696
+ }])
8697
+ }, [divider, vue.createElementVNode("div", {
8698
+ "class": "v-divider__content"
8699
+ }, [slots.default()]), divider]);
8700
+ });
8701
+ return {};
8702
+ }
8703
+ });
8704
+
8533
8705
  // Utilities
8534
8706
 
8535
8707
  // List
8536
8708
  const ListKey = Symbol.for('vuetify:list');
8537
8709
  function createList() {
8710
+ let {
8711
+ filterable
8712
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
8713
+ filterable: false
8714
+ };
8538
8715
  const parent = vue.inject(ListKey, {
8716
+ filterable: false,
8539
8717
  hasPrepend: vue.shallowRef(false),
8540
8718
  updateHasPrepend: () => null
8541
8719
  });
8542
8720
  const data = {
8721
+ filterable: parent.filterable || filterable,
8543
8722
  hasPrepend: vue.shallowRef(false),
8544
8723
  updateHasPrepend: value => {
8545
8724
  if (value) data.hasPrepend.value = value;
@@ -9491,6 +9670,9 @@
9491
9670
  roundedClasses
9492
9671
  } = useRounded(roundedProps);
9493
9672
  const lineClasses = vue.toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
9673
+ const rippleOptions = vue.toRef(() => props.ripple !== undefined && !!props.ripple && list?.filterable ? {
9674
+ keys: [keyCodes.enter]
9675
+ } : props.ripple);
9494
9676
  const slotProps = vue.computed(() => ({
9495
9677
  isActive: isActive.value,
9496
9678
  select,
@@ -9515,8 +9697,9 @@
9515
9697
  function onKeyDown(e) {
9516
9698
  const target = e.target;
9517
9699
  if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
9518
- if (e.key === 'Enter' || e.key === ' ') {
9700
+ if (e.key === 'Enter' || e.key === ' ' && !list?.filterable) {
9519
9701
  e.preventDefault();
9702
+ e.stopPropagation();
9520
9703
  e.target.dispatchEvent(new MouseEvent('click', e));
9521
9704
  }
9522
9705
  }
@@ -9626,7 +9809,7 @@
9626
9809
  }), vue.createElementVNode("div", {
9627
9810
  "class": "v-list-item__spacer"
9628
9811
  }, null)])]
9629
- }), [[Ripple, isClickable.value && props.ripple]]);
9812
+ }), [[Ripple, isClickable.value && rippleOptions.value]]);
9630
9813
  });
9631
9814
  return {
9632
9815
  activate,
@@ -9681,68 +9864,6 @@
9681
9864
  }
9682
9865
  });
9683
9866
 
9684
- const makeVDividerProps = propsFactory({
9685
- color: String,
9686
- inset: Boolean,
9687
- length: [Number, String],
9688
- opacity: [Number, String],
9689
- thickness: [Number, String],
9690
- vertical: Boolean,
9691
- ...makeComponentProps(),
9692
- ...makeThemeProps()
9693
- }, 'VDivider');
9694
- const VDivider = genericComponent()({
9695
- name: 'VDivider',
9696
- props: makeVDividerProps(),
9697
- setup(props, _ref) {
9698
- let {
9699
- attrs,
9700
- slots
9701
- } = _ref;
9702
- const {
9703
- themeClasses
9704
- } = provideTheme(props);
9705
- const {
9706
- textColorClasses,
9707
- textColorStyles
9708
- } = useTextColor(() => props.color);
9709
- const dividerStyles = vue.computed(() => {
9710
- const styles = {};
9711
- if (props.length) {
9712
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9713
- }
9714
- if (props.thickness) {
9715
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9716
- }
9717
- return styles;
9718
- });
9719
- useRender(() => {
9720
- const divider = vue.createElementVNode("hr", {
9721
- "class": vue.normalizeClass([{
9722
- 'v-divider': true,
9723
- 'v-divider--inset': props.inset,
9724
- 'v-divider--vertical': props.vertical
9725
- }, themeClasses.value, textColorClasses.value, props.class]),
9726
- "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
9727
- '--v-border-opacity': props.opacity
9728
- }, props.style]),
9729
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9730
- "role": `${attrs.role || 'separator'}`
9731
- }, null);
9732
- if (!slots.default) return divider;
9733
- return vue.createElementVNode("div", {
9734
- "class": vue.normalizeClass(['v-divider__wrapper', {
9735
- 'v-divider__wrapper--vertical': props.vertical,
9736
- 'v-divider__wrapper--inset': props.inset
9737
- }])
9738
- }, [divider, vue.createElementVNode("div", {
9739
- "class": "v-divider__content"
9740
- }, [slots.default()]), divider]);
9741
- });
9742
- return {};
9743
- }
9744
- });
9745
-
9746
9867
  // Types
9747
9868
 
9748
9869
  const makeVListChildrenProps = propsFactory({
@@ -10011,6 +10132,7 @@
10011
10132
  activeClass: String,
10012
10133
  bgColor: String,
10013
10134
  disabled: Boolean,
10135
+ filterable: Boolean,
10014
10136
  expandIcon: IconValue,
10015
10137
  collapseIcon: IconValue,
10016
10138
  lines: {
@@ -10094,7 +10216,9 @@
10094
10216
  const activeColor = vue.toRef(() => props.activeColor);
10095
10217
  const baseColor = vue.toRef(() => props.baseColor);
10096
10218
  const color = vue.toRef(() => props.color);
10097
- createList();
10219
+ createList({
10220
+ filterable: props.filterable
10221
+ });
10098
10222
  provideDefaults({
10099
10223
  VListGroup: {
10100
10224
  activeColor,
@@ -12670,7 +12794,12 @@
12670
12794
  }
12671
12795
  function calculateOffset(index) {
12672
12796
  index = clamp(index, 0, items.value.length - 1);
12673
- return offsets[index] || 0;
12797
+ const whole = Math.floor(index);
12798
+ const fraction = index % 1;
12799
+ const next = whole + 1;
12800
+ const wholeOffset = offsets[whole] || 0;
12801
+ const nextOffset = offsets[next] || wholeOffset;
12802
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12674
12803
  }
12675
12804
  function calculateIndex(scrollTop) {
12676
12805
  return binaryClosest(offsets, scrollTop);
@@ -13024,6 +13153,7 @@
13024
13153
  },
13025
13154
  openOnClear: Boolean,
13026
13155
  itemColor: String,
13156
+ noAutoScroll: Boolean,
13027
13157
  ...makeItemsProps({
13028
13158
  itemChildren: false
13029
13159
  })
@@ -13238,7 +13368,7 @@
13238
13368
  vue.watch(menu, () => {
13239
13369
  if (!props.hideSelected && menu.value && model.value.length) {
13240
13370
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
13241
- IN_BROWSER && window.requestAnimationFrame(() => {
13371
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
13242
13372
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
13243
13373
  });
13244
13374
  }
@@ -13330,6 +13460,22 @@
13330
13460
  key: item.value,
13331
13461
  onClick: () => select(item, null)
13332
13462
  });
13463
+ if (item.raw.type === 'divider') {
13464
+ return slots.divider?.({
13465
+ props: item.raw,
13466
+ index
13467
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13468
+ "key": `divider-${index}`
13469
+ }), null);
13470
+ }
13471
+ if (item.raw.type === 'subheader') {
13472
+ return slots.subheader?.({
13473
+ props: item.raw,
13474
+ index
13475
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13476
+ "key": `subheader-${index}`
13477
+ }), null);
13478
+ }
13333
13479
  return slots.item?.({
13334
13480
  item,
13335
13481
  index,
@@ -13490,6 +13636,9 @@
13490
13636
  let match = -1;
13491
13637
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13492
13638
  if (typeof item === 'object') {
13639
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13640
+ continue;
13641
+ }
13493
13642
  const filterKeys = keys || Object.keys(transformed);
13494
13643
  for (const key of filterKeys) {
13495
13644
  const value = getPropertyFromItem(transformed, key);
@@ -13692,7 +13841,7 @@
13692
13841
  menu.value = !menu.value;
13693
13842
  }
13694
13843
  function onListKeydown(e) {
13695
- if (e.key !== ' ' && checkPrintable(e)) {
13844
+ if (checkPrintable(e) || e.key === 'Backspace') {
13696
13845
  vTextFieldRef.value?.focus();
13697
13846
  }
13698
13847
  }
@@ -13897,6 +14046,7 @@
13897
14046
  }, props.menuProps), {
13898
14047
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
13899
14048
  "ref": listRef,
14049
+ "filterable": true,
13900
14050
  "selected": selectedValues.value,
13901
14051
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
13902
14052
  "onMousedown": e => e.preventDefault(),
@@ -13928,6 +14078,22 @@
13928
14078
  active: highlightFirst.value && index === 0 ? true : undefined,
13929
14079
  onClick: () => select(item, null)
13930
14080
  });
14081
+ if (item.raw.type === 'divider') {
14082
+ return slots.divider?.({
14083
+ props: item.raw,
14084
+ index
14085
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
14086
+ "key": `divider-${index}`
14087
+ }), null);
14088
+ }
14089
+ if (item.raw.type === 'subheader') {
14090
+ return slots.subheader?.({
14091
+ props: item.raw,
14092
+ index
14093
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
14094
+ "key": `subheader-${index}`
14095
+ }), null);
14096
+ }
13931
14097
  return slots.item?.({
13932
14098
  item,
13933
14099
  index,
@@ -17523,13 +17689,13 @@
17523
17689
  return null;
17524
17690
  }
17525
17691
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17526
- function getWeekdays(locale, firstDayOfWeek) {
17692
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17527
17693
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17528
17694
  return createRange(7).map(i => {
17529
17695
  const weekday = new Date(sundayJanuarySecond2000);
17530
17696
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17531
17697
  return new Intl.DateTimeFormat(locale, {
17532
- weekday: 'narrow'
17698
+ weekday: weekdayFormat ?? 'narrow'
17533
17699
  }).format(weekday);
17534
17700
  });
17535
17701
  }
@@ -17993,9 +18159,9 @@
17993
18159
  getDiff(date, comparing, unit) {
17994
18160
  return getDiff(date, comparing, unit);
17995
18161
  }
17996
- getWeekdays(firstDayOfWeek) {
18162
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17997
18163
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17998
- return getWeekdays(this.locale, firstDay);
18164
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17999
18165
  }
18000
18166
  getYear(date) {
18001
18167
  return getYear(date);
@@ -18338,6 +18504,7 @@
18338
18504
  _search.value = val ?? '';
18339
18505
  if (!props.multiple && !hasSelectionSlot.value) {
18340
18506
  model.value = [transformItem$3(props, val)];
18507
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18341
18508
  }
18342
18509
  if (val && props.multiple && props.delimiters?.length) {
18343
18510
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18418,7 +18585,7 @@
18418
18585
  menu.value = !menu.value;
18419
18586
  }
18420
18587
  function onListKeydown(e) {
18421
- if (e.key !== ' ' && checkPrintable(e)) {
18588
+ if (checkPrintable(e) || e.key === 'Backspace') {
18422
18589
  vTextFieldRef.value?.focus();
18423
18590
  }
18424
18591
  }
@@ -18623,6 +18790,7 @@
18623
18790
  }, props.menuProps), {
18624
18791
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18625
18792
  "ref": listRef,
18793
+ "filterable": true,
18626
18794
  "selected": selectedValues.value,
18627
18795
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18628
18796
  "onMousedown": e => e.preventDefault(),
@@ -18654,6 +18822,22 @@
18654
18822
  active: highlightFirst.value && index === 0 ? true : undefined,
18655
18823
  onClick: () => select(item, null)
18656
18824
  });
18825
+ if (item.raw.type === 'divider') {
18826
+ return slots.divider?.({
18827
+ props: item.raw,
18828
+ index
18829
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18830
+ "key": `divider-${index}`
18831
+ }), null);
18832
+ }
18833
+ if (item.raw.type === 'subheader') {
18834
+ return slots.subheader?.({
18835
+ props: item.raw,
18836
+ index
18837
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18838
+ "key": `subheader-${index}`
18839
+ }), null);
18840
+ }
18657
18841
  return slots.item?.({
18658
18842
  item,
18659
18843
  index,
@@ -20533,6 +20717,7 @@
20533
20717
  color: String,
20534
20718
  disableSort: Boolean,
20535
20719
  fixedHeader: Boolean,
20720
+ lastFixed: Boolean,
20536
20721
  multiSort: Boolean,
20537
20722
  sortAscIcon: {
20538
20723
  type: IconValue,
@@ -20579,10 +20764,11 @@
20579
20764
  loaderClasses
20580
20765
  } = useLoader(props);
20581
20766
  function getFixedStyles(column, y) {
20582
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20767
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20583
20768
  return {
20584
20769
  position: 'sticky',
20585
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20770
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20771
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20586
20772
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20587
20773
  };
20588
20774
  }
@@ -22297,7 +22483,8 @@
22297
22483
  firstDayOfWeek: {
22298
22484
  type: [Number, String],
22299
22485
  default: undefined
22300
- }
22486
+ },
22487
+ weekdayFormat: String
22301
22488
  }, 'calendar');
22302
22489
  function useCalendar(props) {
22303
22490
  const adapter = useDate();
@@ -22545,7 +22732,7 @@
22545
22732
  "ref": daysRef,
22546
22733
  "key": daysInMonth.value[0].date?.toString(),
22547
22734
  "class": "v-date-picker-month__days"
22548
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => vue.createElementVNode("div", {
22735
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => vue.createElementVNode("div", {
22549
22736
  "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
22550
22737
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22551
22738
  const slotProps = {
@@ -25076,6 +25263,10 @@
25076
25263
  type: Number,
25077
25264
  default: 0
25078
25265
  },
25266
+ minFractionDigits: {
25267
+ type: Number,
25268
+ default: null
25269
+ },
25079
25270
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
25080
25271
  }, 'VNumberInput');
25081
25272
  const VNumberInput = genericComponent()({
@@ -25106,9 +25297,19 @@
25106
25297
  } = useFocus(props);
25107
25298
  function correctPrecision(val) {
25108
25299
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
25109
- const fixed = precision == null ? String(val) : val.toFixed(precision);
25110
- return isFocused.value ? Number(fixed).toString() // trim zeros
25111
- : fixed;
25300
+ if (precision == null) {
25301
+ return String(val);
25302
+ }
25303
+ let fixed = val.toFixed(precision);
25304
+ if (isFocused.value) {
25305
+ return Number(fixed).toString(); // trim zeros
25306
+ }
25307
+ if ((props.minFractionDigits ?? precision) < precision) {
25308
+ const trimLimit = precision - props.minFractionDigits;
25309
+ const [baseDigits, fractionDigits] = fixed.split('.');
25310
+ fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
25311
+ }
25312
+ return fixed;
25112
25313
  }
25113
25314
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
25114
25315
  const _inputText = vue.shallowRef(null);
@@ -25167,6 +25368,7 @@
25167
25368
  }
25168
25369
  };
25169
25370
  vue.watch(() => props.precision, () => formatInputValue());
25371
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
25170
25372
  vue.onMounted(() => {
25171
25373
  clampModel();
25172
25374
  });
@@ -25276,7 +25478,7 @@
25276
25478
  inputText.value = null;
25277
25479
  return;
25278
25480
  }
25279
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25481
+ inputText.value = correctPrecision(model.value);
25280
25482
  }
25281
25483
  function trimDecimalZeros() {
25282
25484
  if (controlsDisabled.value) return;
@@ -25536,9 +25738,10 @@
25536
25738
  e.preventDefault();
25537
25739
  e.stopPropagation();
25538
25740
  const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
25741
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25539
25742
  if (isValidNumber(clipboardText)) return;
25540
25743
  model.value = clipboardText.split('');
25541
- inputRef.value?.[index].blur();
25744
+ inputRef.value?.[finalIndex].focus();
25542
25745
  }
25543
25746
  function reset() {
25544
25747
  model.value = [];
@@ -29320,7 +29523,7 @@
29320
29523
  };
29321
29524
  });
29322
29525
  }
29323
- const version$1 = "3.8.6-master.2025-05-26";
29526
+ const version$1 = "3.8.7-dev.2025-05-30";
29324
29527
  createVuetify$1.version = version$1;
29325
29528
 
29326
29529
  // Vue's inject() can only be used in setup
@@ -29345,7 +29548,7 @@
29345
29548
  ...options
29346
29549
  });
29347
29550
  };
29348
- const version = "3.8.6-master.2025-05-26";
29551
+ const version = "3.8.7-dev.2025-05-30";
29349
29552
  createVuetify.version = version;
29350
29553
 
29351
29554
  exports.blueprints = index;