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

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 (117) hide show
  1. package/CHANGELOG.md +24 -24
  2. package/dist/json/attributes.json +3294 -3218
  3. package/dist/json/importMap-labs.json +26 -26
  4. package/dist/json/importMap.json +192 -192
  5. package/dist/json/tags.json +19 -0
  6. package/dist/json/web-types.json +5776 -5504
  7. package/dist/vuetify-labs.cjs +305 -128
  8. package/dist/vuetify-labs.css +5202 -5174
  9. package/dist/vuetify-labs.d.ts +1580 -1351
  10. package/dist/vuetify-labs.esm.js +306 -129
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +305 -128
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +299 -117
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +4512 -4484
  17. package/dist/vuetify.d.ts +739 -518
  18. package/dist/vuetify.esm.js +300 -118
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +299 -117
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1194 -1184
  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/VAutocomplete/VAutocomplete.d.ts +133 -96
  31. package/lib/components/VAutocomplete/VAutocomplete.js +19 -2
  32. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  33. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  34. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  35. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  36. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  37. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  38. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  39. package/lib/components/VCheckbox/VCheckbox.d.ts +3 -3
  40. package/lib/components/VChipGroup/VChipGroup.d.ts +10 -0
  41. package/lib/components/VCombobox/VCombobox.d.ts +133 -96
  42. package/lib/components/VCombobox/VCombobox.js +20 -2
  43. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  44. package/lib/components/VDataTable/VDataTable.d.ts +18 -0
  45. package/lib/components/VDataTable/VDataTableHeaders.d.ts +13 -0
  46. package/lib/components/VDataTable/VDataTableHeaders.js +4 -2
  47. package/lib/components/VDataTable/VDataTableHeaders.js.map +1 -1
  48. package/lib/components/VDataTable/VDataTableServer.d.ts +13 -0
  49. package/lib/components/VDataTable/VDataTableVirtual.d.ts +13 -0
  50. package/lib/components/VDatePicker/VDatePicker.d.ts +10 -0
  51. package/lib/components/VDatePicker/VDatePickerMonth.d.ts +10 -0
  52. package/lib/components/VDatePicker/VDatePickerMonth.js +1 -1
  53. package/lib/components/VDatePicker/VDatePickerMonth.js.map +1 -1
  54. package/lib/components/VField/VField.d.ts +3 -3
  55. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  56. package/lib/components/VInput/VInput.d.ts +4 -4
  57. package/lib/components/VList/VListChildren.js.map +1 -1
  58. package/lib/components/VNumberInput/VNumberInput.d.ts +103 -89
  59. package/lib/components/VNumberInput/VNumberInput.js +19 -4
  60. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  61. package/lib/components/VOtpInput/VOtpInput.js +2 -1
  62. package/lib/components/VOtpInput/VOtpInput.js.map +1 -1
  63. package/lib/components/VOverlay/VOverlay.css +1 -1
  64. package/lib/components/VOverlay/_variables.scss +1 -1
  65. package/lib/components/VRadioGroup/VRadioGroup.d.ts +3 -3
  66. package/lib/components/VRangeSlider/VRangeSlider.d.ts +3 -3
  67. package/lib/components/VSelect/VSelect.d.ts +138 -96
  68. package/lib/components/VSelect/VSelect.js +21 -3
  69. package/lib/components/VSelect/VSelect.js.map +1 -1
  70. package/lib/components/VSlideGroup/VSlideGroup.d.ts +10 -0
  71. package/lib/components/VSlideGroup/VSlideGroup.js +2 -1
  72. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  73. package/lib/components/VSlider/VSlider.d.ts +3 -3
  74. package/lib/components/VSwitch/VSwitch.d.ts +3 -3
  75. package/lib/components/VTabs/VTabs.d.ts +10 -0
  76. package/lib/components/VTextField/VTextField.d.ts +27 -27
  77. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  78. package/lib/composables/calendar.d.ts +6 -0
  79. package/lib/composables/calendar.js +2 -1
  80. package/lib/composables/calendar.js.map +1 -1
  81. package/lib/composables/date/DateAdapter.d.ts +1 -1
  82. package/lib/composables/date/DateAdapter.js.map +1 -1
  83. package/lib/composables/date/adapters/vuetify.d.ts +1 -1
  84. package/lib/composables/date/adapters/vuetify.js +4 -4
  85. package/lib/composables/date/adapters/vuetify.js.map +1 -1
  86. package/lib/composables/date/date.d.ts +1 -1
  87. package/lib/composables/date/index.d.ts +1 -0
  88. package/lib/composables/date/index.js +1 -0
  89. package/lib/composables/date/index.js.map +1 -1
  90. package/lib/composables/filter.js +3 -0
  91. package/lib/composables/filter.js.map +1 -1
  92. package/lib/composables/iconSizes.d.ts +28 -0
  93. package/lib/composables/iconSizes.js +23 -0
  94. package/lib/composables/iconSizes.js.map +1 -0
  95. package/lib/composables/theme.d.ts +6 -1
  96. package/lib/composables/theme.js +94 -26
  97. package/lib/composables/theme.js.map +1 -1
  98. package/lib/composables/virtual.js +6 -1
  99. package/lib/composables/virtual.js.map +1 -1
  100. package/lib/entry-bundler.d.ts +1 -1
  101. package/lib/entry-bundler.js +1 -1
  102. package/lib/entry-bundler.js.map +1 -1
  103. package/lib/framework.d.ts +73 -68
  104. package/lib/framework.js +1 -1
  105. package/lib/framework.js.map +1 -1
  106. package/lib/labs/VCalendar/VCalendar.d.ts +10 -0
  107. package/lib/labs/VColorInput/VColorInput.d.ts +3 -3
  108. package/lib/labs/VDateInput/VDateInput.d.ts +97 -87
  109. package/lib/labs/VFileUpload/VFileUpload.d.ts +3 -3
  110. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  111. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  112. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  113. package/lib/labs/entry-bundler.d.ts +1 -1
  114. package/lib/util/globals.d.ts +1 -0
  115. package/lib/util/globals.js +1 -0
  116. package/lib/util/globals.js.map +1 -1
  117. package/package.json +3 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.6-master.2025-05-26
2
+ * Vuetify v3.8.7-dev.2025-05-27
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -85,6 +85,7 @@
85
85
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
86
86
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
87
87
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
88
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
88
89
 
89
90
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
90
91
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -2341,6 +2342,7 @@
2341
2342
  function genDefaults$2() {
2342
2343
  return {
2343
2344
  defaultTheme: 'light',
2345
+ prefix: 'v-',
2344
2346
  variations: {
2345
2347
  colors: [],
2346
2348
  lighten: 0,
@@ -2422,7 +2424,10 @@
2422
2424
  }
2423
2425
  }
2424
2426
  },
2425
- stylesheetId: 'vuetify-theme-stylesheet'
2427
+ stylesheetId: 'vuetify-theme-stylesheet',
2428
+ scoped: false,
2429
+ unimportant: false,
2430
+ utilities: true
2426
2431
  };
2427
2432
  }
2428
2433
  function parseThemeOptions() {
@@ -2445,21 +2450,21 @@
2445
2450
  function createCssClass(lines, selector, content, scope) {
2446
2451
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2447
2452
  }
2448
- function genCssVariables(theme) {
2453
+ function genCssVariables(theme, prefix) {
2449
2454
  const lightOverlay = theme.dark ? 2 : 1;
2450
2455
  const darkOverlay = theme.dark ? 1 : 2;
2451
2456
  const variables = [];
2452
2457
  for (const [key, value] of Object.entries(theme.colors)) {
2453
2458
  const rgb = parseColor(value);
2454
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2459
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2455
2460
  if (!key.startsWith('on-')) {
2456
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2461
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2457
2462
  }
2458
2463
  }
2459
2464
  for (const [key, value] of Object.entries(theme.variables)) {
2460
2465
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2461
2466
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2462
- variables.push(`--v-${key}: ${rgb ?? value}`);
2467
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2463
2468
  }
2464
2469
  return variables;
2465
2470
  }
@@ -2503,7 +2508,8 @@
2503
2508
  const scopeSelector = `:where(${scope})`;
2504
2509
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2505
2510
  }
2506
- function upsertStyles(styleEl, styles) {
2511
+ function upsertStyles(id, cspNonce, styles) {
2512
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2507
2513
  if (!styleEl) return;
2508
2514
  styleEl.innerHTML = styles;
2509
2515
  }
@@ -2523,8 +2529,17 @@
2523
2529
  // Composables
2524
2530
  function createTheme(options) {
2525
2531
  const parsedOptions = parseThemeOptions(options);
2526
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2532
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2527
2533
  const themes = vue.ref(parsedOptions.themes);
2534
+ const systemName = vue.shallowRef('light');
2535
+ const name = vue.computed({
2536
+ get() {
2537
+ return _name.value === 'system' ? systemName.value : _name.value;
2538
+ },
2539
+ set(val) {
2540
+ _name.value = val;
2541
+ }
2542
+ });
2528
2543
  const computedThemes = vue.computed(() => {
2529
2544
  const acc = {};
2530
2545
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2545,28 +2560,49 @@
2545
2560
  const current = vue.toRef(() => computedThemes.value[name.value]);
2546
2561
  const styles = vue.computed(() => {
2547
2562
  const lines = [];
2563
+ const important = parsedOptions.unimportant ? '' : ' !important';
2564
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2548
2565
  if (current.value?.dark) {
2549
2566
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2550
2567
  }
2551
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2568
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2552
2569
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2553
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2554
- }
2555
- const bgLines = [];
2556
- const fgLines = [];
2557
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2558
- for (const key of colors) {
2559
- if (key.startsWith('on-')) {
2560
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2561
- } else {
2562
- createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`], parsedOptions.scope);
2563
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2564
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2570
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2571
+ }
2572
+ if (parsedOptions.utilities) {
2573
+ const bgLines = [];
2574
+ const fgLines = [];
2575
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2576
+ for (const key of colors) {
2577
+ if (key.startsWith('on-')) {
2578
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2579
+ } else {
2580
+ 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);
2581
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2582
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2583
+ }
2565
2584
  }
2585
+ lines.push(...bgLines, ...fgLines);
2566
2586
  }
2567
- lines.push(...bgLines, ...fgLines);
2568
2587
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2569
2588
  });
2589
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2590
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2591
+ if (SUPPORTS_MATCH_MEDIA) {
2592
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2593
+ function updateSystemName() {
2594
+ systemName.value = media.matches ? 'dark' : 'light';
2595
+ }
2596
+ updateSystemName();
2597
+ media.addEventListener('change', updateSystemName, {
2598
+ passive: true
2599
+ });
2600
+ if (vue.getCurrentScope()) {
2601
+ vue.onScopeDispose(() => {
2602
+ media.removeEventListener('change', updateSystemName);
2603
+ });
2604
+ }
2605
+ }
2570
2606
  function install(app) {
2571
2607
  if (parsedOptions.isDisabled) return;
2572
2608
  const head = app._context.provides.usehead;
@@ -2604,22 +2640,55 @@
2604
2640
  updateStyles();
2605
2641
  }
2606
2642
  function updateStyles() {
2607
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2643
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2608
2644
  }
2609
2645
  }
2610
2646
  }
2611
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2647
+ function change(themeName) {
2648
+ if (!themeNames.value.includes(themeName)) {
2649
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2650
+ return;
2651
+ }
2652
+ name.value = themeName;
2653
+ }
2654
+ function cycle() {
2655
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2656
+ const currentIndex = themeArray.indexOf(name.value);
2657
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2658
+ change(themeArray[nextIndex]);
2659
+ }
2660
+ function toggle() {
2661
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2662
+ cycle(themeArray);
2663
+ }
2664
+ const globalName = new Proxy(name, {
2665
+ get(target, prop) {
2666
+ return target[prop];
2667
+ },
2668
+ set(target, prop, val) {
2669
+ if (prop === 'value') {
2670
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2671
+ }
2672
+ // @ts-expect-error
2673
+ target[prop] = val;
2674
+ return true;
2675
+ }
2676
+ });
2612
2677
  return {
2613
2678
  install,
2679
+ change,
2680
+ cycle,
2681
+ toggle,
2614
2682
  isDisabled: parsedOptions.isDisabled,
2615
2683
  name,
2616
2684
  themes,
2617
2685
  current,
2618
2686
  computedThemes,
2687
+ prefix: parsedOptions.prefix,
2619
2688
  themeClasses,
2620
2689
  styles,
2621
2690
  global: {
2622
- name,
2691
+ name: globalName,
2623
2692
  current
2624
2693
  }
2625
2694
  };
@@ -2630,7 +2699,7 @@
2630
2699
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2631
2700
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2632
2701
  const current = vue.toRef(() => theme.themes.value[name.value]);
2633
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2702
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2634
2703
  const newTheme = {
2635
2704
  ...theme,
2636
2705
  name,
@@ -4177,9 +4246,15 @@
4177
4246
  };
4178
4247
  }
4179
4248
 
4249
+ // Types
4250
+
4180
4251
  const makeVBtnGroupProps = propsFactory({
4181
4252
  baseColor: String,
4182
4253
  divided: Boolean,
4254
+ direction: {
4255
+ type: String,
4256
+ default: 'horizontal'
4257
+ },
4183
4258
  ...makeBorderProps(),
4184
4259
  ...makeComponentProps(),
4185
4260
  ...makeDensityProps(),
@@ -4213,7 +4288,7 @@
4213
4288
  } = useRounded(props);
4214
4289
  provideDefaults({
4215
4290
  VBtn: {
4216
- height: 'auto',
4291
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4217
4292
  baseColor: vue.toRef(() => props.baseColor),
4218
4293
  color: vue.toRef(() => props.color),
4219
4294
  density: vue.toRef(() => props.density),
@@ -4223,7 +4298,7 @@
4223
4298
  });
4224
4299
  useRender(() => {
4225
4300
  return vue.createVNode(props.tag, {
4226
- "class": vue.normalizeClass(['v-btn-group', {
4301
+ "class": vue.normalizeClass(['v-btn-group', `v-btn-group--${props.direction}`, {
4227
4302
  'v-btn-group--divided': props.divided
4228
4303
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
4229
4304
  "style": vue.normalizeStyle(props.style)
@@ -5911,6 +5986,31 @@
5911
5986
  // Utilities
5912
5987
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5913
5988
 
5989
+ // Utilities
5990
+
5991
+ // Types
5992
+
5993
+ // Types
5994
+
5995
+ // Composables
5996
+ const makeIconSizeProps = propsFactory({
5997
+ iconSize: [Number, String],
5998
+ iconSizes: {
5999
+ type: Array,
6000
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6001
+ }
6002
+ }, 'iconSize');
6003
+ function useIconSizes(props, fallback) {
6004
+ const iconSize = vue.computed(() => {
6005
+ const iconSizeMap = new Map(props.iconSizes);
6006
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6007
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6008
+ });
6009
+ return {
6010
+ iconSize
6011
+ };
6012
+ }
6013
+
5914
6014
  // Types
5915
6015
 
5916
6016
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5950,6 +6050,7 @@
5950
6050
  ...makeDensityProps(),
5951
6051
  ...makeDimensionProps(),
5952
6052
  ...makeElevationProps(),
6053
+ ...makeIconSizeProps(),
5953
6054
  ...makeLocationProps(),
5954
6055
  ...makePositionProps(),
5955
6056
  ...makeRoundedProps(),
@@ -5977,6 +6078,9 @@
5977
6078
  if (!props.type) return props.icon;
5978
6079
  return props.icon ?? `$${props.type}`;
5979
6080
  });
6081
+ const {
6082
+ iconSize
6083
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5980
6084
  const {
5981
6085
  themeClasses
5982
6086
  } = provideTheme(props);
@@ -6024,6 +6128,11 @@
6024
6128
  const hasPrepend = !!(slots.prepend || icon.value);
6025
6129
  const hasTitle = !!(slots.title || props.title);
6026
6130
  const hasClose = !!(slots.close || props.closable);
6131
+ const iconProps = {
6132
+ density: props.density,
6133
+ icon: icon.value,
6134
+ size: iconSize.value
6135
+ };
6027
6136
  return isActive.value && vue.createVNode(props.tag, {
6028
6137
  "class": vue.normalizeClass(['v-alert', props.border && {
6029
6138
  'v-alert--border': !!props.border,
@@ -6041,19 +6150,14 @@
6041
6150
  }, null), hasPrepend && vue.createElementVNode("div", {
6042
6151
  "key": "prepend",
6043
6152
  "class": "v-alert__prepend"
6044
- }, [!slots.prepend ? vue.createVNode(VIcon, {
6045
- "key": "prepend-icon",
6046
- "density": props.density,
6047
- "icon": icon.value,
6048
- "size": props.prominent ? 44 : 28
6049
- }, null) : vue.createVNode(VDefaultsProvider, {
6153
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6154
+ "key": "prepend-icon"
6155
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6050
6156
  "key": "prepend-defaults",
6051
6157
  "disabled": !icon.value,
6052
6158
  "defaults": {
6053
6159
  VIcon: {
6054
- density: props.density,
6055
- icon: icon.value,
6056
- size: props.prominent ? 44 : 28
6160
+ ...iconProps
6057
6161
  }
6058
6162
  }
6059
6163
  }, slots.prepend)]), vue.createElementVNode("div", {
@@ -7578,6 +7682,7 @@
7578
7682
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7579
7683
  const makeVSlideGroupProps = propsFactory({
7580
7684
  centerActive: Boolean,
7685
+ contentClass: null,
7581
7686
  direction: {
7582
7687
  type: String,
7583
7688
  default: 'horizontal'
@@ -7890,7 +7995,7 @@
7890
7995
  })]), vue.createElementVNode("div", {
7891
7996
  "key": "container",
7892
7997
  "ref": containerRef,
7893
- "class": "v-slide-group__container",
7998
+ "class": vue.normalizeClass(['v-slide-group__container', props.contentClass]),
7894
7999
  "onScroll": onScroll
7895
8000
  }, [vue.createElementVNode("div", {
7896
8001
  "ref": contentRef,
@@ -8252,6 +8357,68 @@
8252
8357
  }
8253
8358
  });
8254
8359
 
8360
+ const makeVDividerProps = propsFactory({
8361
+ color: String,
8362
+ inset: Boolean,
8363
+ length: [Number, String],
8364
+ opacity: [Number, String],
8365
+ thickness: [Number, String],
8366
+ vertical: Boolean,
8367
+ ...makeComponentProps(),
8368
+ ...makeThemeProps()
8369
+ }, 'VDivider');
8370
+ const VDivider = genericComponent()({
8371
+ name: 'VDivider',
8372
+ props: makeVDividerProps(),
8373
+ setup(props, _ref) {
8374
+ let {
8375
+ attrs,
8376
+ slots
8377
+ } = _ref;
8378
+ const {
8379
+ themeClasses
8380
+ } = provideTheme(props);
8381
+ const {
8382
+ textColorClasses,
8383
+ textColorStyles
8384
+ } = useTextColor(() => props.color);
8385
+ const dividerStyles = vue.computed(() => {
8386
+ const styles = {};
8387
+ if (props.length) {
8388
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8389
+ }
8390
+ if (props.thickness) {
8391
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8392
+ }
8393
+ return styles;
8394
+ });
8395
+ useRender(() => {
8396
+ const divider = vue.createElementVNode("hr", {
8397
+ "class": vue.normalizeClass([{
8398
+ 'v-divider': true,
8399
+ 'v-divider--inset': props.inset,
8400
+ 'v-divider--vertical': props.vertical
8401
+ }, themeClasses.value, textColorClasses.value, props.class]),
8402
+ "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
8403
+ '--v-border-opacity': props.opacity
8404
+ }, props.style]),
8405
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8406
+ "role": `${attrs.role || 'separator'}`
8407
+ }, null);
8408
+ if (!slots.default) return divider;
8409
+ return vue.createElementVNode("div", {
8410
+ "class": vue.normalizeClass(['v-divider__wrapper', {
8411
+ 'v-divider__wrapper--vertical': props.vertical,
8412
+ 'v-divider__wrapper--inset': props.inset
8413
+ }])
8414
+ }, [divider, vue.createElementVNode("div", {
8415
+ "class": "v-divider__content"
8416
+ }, [slots.default()]), divider]);
8417
+ });
8418
+ return {};
8419
+ }
8420
+ });
8421
+
8255
8422
  // Utilities
8256
8423
 
8257
8424
  // List
@@ -9403,68 +9570,6 @@
9403
9570
  }
9404
9571
  });
9405
9572
 
9406
- const makeVDividerProps = propsFactory({
9407
- color: String,
9408
- inset: Boolean,
9409
- length: [Number, String],
9410
- opacity: [Number, String],
9411
- thickness: [Number, String],
9412
- vertical: Boolean,
9413
- ...makeComponentProps(),
9414
- ...makeThemeProps()
9415
- }, 'VDivider');
9416
- const VDivider = genericComponent()({
9417
- name: 'VDivider',
9418
- props: makeVDividerProps(),
9419
- setup(props, _ref) {
9420
- let {
9421
- attrs,
9422
- slots
9423
- } = _ref;
9424
- const {
9425
- themeClasses
9426
- } = provideTheme(props);
9427
- const {
9428
- textColorClasses,
9429
- textColorStyles
9430
- } = useTextColor(() => props.color);
9431
- const dividerStyles = vue.computed(() => {
9432
- const styles = {};
9433
- if (props.length) {
9434
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9435
- }
9436
- if (props.thickness) {
9437
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9438
- }
9439
- return styles;
9440
- });
9441
- useRender(() => {
9442
- const divider = vue.createElementVNode("hr", {
9443
- "class": vue.normalizeClass([{
9444
- 'v-divider': true,
9445
- 'v-divider--inset': props.inset,
9446
- 'v-divider--vertical': props.vertical
9447
- }, themeClasses.value, textColorClasses.value, props.class]),
9448
- "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
9449
- '--v-border-opacity': props.opacity
9450
- }, props.style]),
9451
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9452
- "role": `${attrs.role || 'separator'}`
9453
- }, null);
9454
- if (!slots.default) return divider;
9455
- return vue.createElementVNode("div", {
9456
- "class": vue.normalizeClass(['v-divider__wrapper', {
9457
- 'v-divider__wrapper--vertical': props.vertical,
9458
- 'v-divider__wrapper--inset': props.inset
9459
- }])
9460
- }, [divider, vue.createElementVNode("div", {
9461
- "class": "v-divider__content"
9462
- }, [slots.default()]), divider]);
9463
- });
9464
- return {};
9465
- }
9466
- });
9467
-
9468
9573
  // Types
9469
9574
 
9470
9575
  const makeVListChildrenProps = propsFactory({
@@ -12392,7 +12497,12 @@
12392
12497
  }
12393
12498
  function calculateOffset(index) {
12394
12499
  index = clamp(index, 0, items.value.length - 1);
12395
- return offsets[index] || 0;
12500
+ const whole = Math.floor(index);
12501
+ const fraction = index % 1;
12502
+ const next = whole + 1;
12503
+ const wholeOffset = offsets[whole] || 0;
12504
+ const nextOffset = offsets[next] || wholeOffset;
12505
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12396
12506
  }
12397
12507
  function calculateIndex(scrollTop) {
12398
12508
  return binaryClosest(offsets, scrollTop);
@@ -12746,6 +12856,7 @@
12746
12856
  },
12747
12857
  openOnClear: Boolean,
12748
12858
  itemColor: String,
12859
+ noAutoScroll: Boolean,
12749
12860
  ...makeItemsProps({
12750
12861
  itemChildren: false
12751
12862
  })
@@ -12960,7 +13071,7 @@
12960
13071
  vue.watch(menu, () => {
12961
13072
  if (!props.hideSelected && menu.value && model.value.length) {
12962
13073
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
12963
- IN_BROWSER && window.requestAnimationFrame(() => {
13074
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
12964
13075
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
12965
13076
  });
12966
13077
  }
@@ -13052,6 +13163,22 @@
13052
13163
  key: item.value,
13053
13164
  onClick: () => select(item, null)
13054
13165
  });
13166
+ if (item.raw.type === 'divider') {
13167
+ return slots.divider?.({
13168
+ props: item.raw,
13169
+ index
13170
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13171
+ "key": `divider-${index}`
13172
+ }), null);
13173
+ }
13174
+ if (item.raw.type === 'subheader') {
13175
+ return slots.subheader?.({
13176
+ props: item.raw,
13177
+ index
13178
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13179
+ "key": `subheader-${index}`
13180
+ }), null);
13181
+ }
13055
13182
  return slots.item?.({
13056
13183
  item,
13057
13184
  index,
@@ -13212,6 +13339,9 @@
13212
13339
  let match = -1;
13213
13340
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13214
13341
  if (typeof item === 'object') {
13342
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13343
+ continue;
13344
+ }
13215
13345
  const filterKeys = keys || Object.keys(transformed);
13216
13346
  for (const key of filterKeys) {
13217
13347
  const value = getPropertyFromItem(transformed, key);
@@ -13650,6 +13780,22 @@
13650
13780
  active: highlightFirst.value && index === 0 ? true : undefined,
13651
13781
  onClick: () => select(item, null)
13652
13782
  });
13783
+ if (item.raw.type === 'divider') {
13784
+ return slots.divider?.({
13785
+ props: item.raw,
13786
+ index
13787
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13788
+ "key": `divider-${index}`
13789
+ }), null);
13790
+ }
13791
+ if (item.raw.type === 'subheader') {
13792
+ return slots.subheader?.({
13793
+ props: item.raw,
13794
+ index
13795
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13796
+ "key": `subheader-${index}`
13797
+ }), null);
13798
+ }
13653
13799
  return slots.item?.({
13654
13800
  item,
13655
13801
  index,
@@ -17245,13 +17391,13 @@
17245
17391
  return null;
17246
17392
  }
17247
17393
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17248
- function getWeekdays(locale, firstDayOfWeek) {
17394
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17249
17395
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17250
17396
  return createRange(7).map(i => {
17251
17397
  const weekday = new Date(sundayJanuarySecond2000);
17252
17398
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17253
17399
  return new Intl.DateTimeFormat(locale, {
17254
- weekday: 'narrow'
17400
+ weekday: weekdayFormat ?? 'narrow'
17255
17401
  }).format(weekday);
17256
17402
  });
17257
17403
  }
@@ -17715,9 +17861,9 @@
17715
17861
  getDiff(date, comparing, unit) {
17716
17862
  return getDiff(date, comparing, unit);
17717
17863
  }
17718
- getWeekdays(firstDayOfWeek) {
17864
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17719
17865
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17720
- return getWeekdays(this.locale, firstDay);
17866
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17721
17867
  }
17722
17868
  getYear(date) {
17723
17869
  return getYear(date);
@@ -18060,6 +18206,7 @@
18060
18206
  _search.value = val ?? '';
18061
18207
  if (!props.multiple && !hasSelectionSlot.value) {
18062
18208
  model.value = [transformItem$3(props, val)];
18209
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18063
18210
  }
18064
18211
  if (val && props.multiple && props.delimiters?.length) {
18065
18212
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18376,6 +18523,22 @@
18376
18523
  active: highlightFirst.value && index === 0 ? true : undefined,
18377
18524
  onClick: () => select(item, null)
18378
18525
  });
18526
+ if (item.raw.type === 'divider') {
18527
+ return slots.divider?.({
18528
+ props: item.raw,
18529
+ index
18530
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18531
+ "key": `divider-${index}`
18532
+ }), null);
18533
+ }
18534
+ if (item.raw.type === 'subheader') {
18535
+ return slots.subheader?.({
18536
+ props: item.raw,
18537
+ index
18538
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18539
+ "key": `subheader-${index}`
18540
+ }), null);
18541
+ }
18379
18542
  return slots.item?.({
18380
18543
  item,
18381
18544
  index,
@@ -20255,6 +20418,7 @@
20255
20418
  color: String,
20256
20419
  disableSort: Boolean,
20257
20420
  fixedHeader: Boolean,
20421
+ lastFixed: Boolean,
20258
20422
  multiSort: Boolean,
20259
20423
  sortAscIcon: {
20260
20424
  type: IconValue,
@@ -20301,10 +20465,11 @@
20301
20465
  loaderClasses
20302
20466
  } = useLoader(props);
20303
20467
  function getFixedStyles(column, y) {
20304
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20468
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20305
20469
  return {
20306
20470
  position: 'sticky',
20307
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20471
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20472
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20308
20473
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20309
20474
  };
20310
20475
  }
@@ -22019,7 +22184,8 @@
22019
22184
  firstDayOfWeek: {
22020
22185
  type: [Number, String],
22021
22186
  default: undefined
22022
- }
22187
+ },
22188
+ weekdayFormat: String
22023
22189
  }, 'calendar');
22024
22190
  function useCalendar(props) {
22025
22191
  const adapter = useDate();
@@ -22267,7 +22433,7 @@
22267
22433
  "ref": daysRef,
22268
22434
  "key": daysInMonth.value[0].date?.toString(),
22269
22435
  "class": "v-date-picker-month__days"
22270
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => vue.createElementVNode("div", {
22436
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => vue.createElementVNode("div", {
22271
22437
  "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
22272
22438
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22273
22439
  const slotProps = {
@@ -24798,6 +24964,10 @@
24798
24964
  type: Number,
24799
24965
  default: 0
24800
24966
  },
24967
+ minFractionDigits: {
24968
+ type: Number,
24969
+ default: null
24970
+ },
24801
24971
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24802
24972
  }, 'VNumberInput');
24803
24973
  const VNumberInput = genericComponent()({
@@ -24828,9 +24998,19 @@
24828
24998
  } = useFocus(props);
24829
24999
  function correctPrecision(val) {
24830
25000
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
24831
- const fixed = precision == null ? String(val) : val.toFixed(precision);
24832
- return isFocused.value ? Number(fixed).toString() // trim zeros
24833
- : fixed;
25001
+ if (precision == null) {
25002
+ return String(val);
25003
+ }
25004
+ let fixed = val.toFixed(precision);
25005
+ if (isFocused.value) {
25006
+ return Number(fixed).toString(); // trim zeros
25007
+ }
25008
+ if ((props.minFractionDigits ?? precision) < precision) {
25009
+ const trimLimit = precision - props.minFractionDigits;
25010
+ const [baseDigits, fractionDigits] = fixed.split('.');
25011
+ fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
25012
+ }
25013
+ return fixed;
24834
25014
  }
24835
25015
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24836
25016
  const _inputText = vue.shallowRef(null);
@@ -24889,6 +25069,7 @@
24889
25069
  }
24890
25070
  };
24891
25071
  vue.watch(() => props.precision, () => formatInputValue());
25072
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
24892
25073
  vue.onMounted(() => {
24893
25074
  clampModel();
24894
25075
  });
@@ -24998,7 +25179,7 @@
24998
25179
  inputText.value = null;
24999
25180
  return;
25000
25181
  }
25001
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25182
+ inputText.value = correctPrecision(model.value);
25002
25183
  }
25003
25184
  function trimDecimalZeros() {
25004
25185
  if (controlsDisabled.value) return;
@@ -25258,9 +25439,10 @@
25258
25439
  e.preventDefault();
25259
25440
  e.stopPropagation();
25260
25441
  const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
25442
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25261
25443
  if (isValidNumber(clipboardText)) return;
25262
25444
  model.value = clipboardText.split('');
25263
- inputRef.value?.[index].blur();
25445
+ inputRef.value?.[finalIndex].focus();
25264
25446
  }
25265
25447
  function reset() {
25266
25448
  model.value = [];
@@ -29967,11 +30149,6 @@
29967
30149
  hideOverlay: Boolean,
29968
30150
  icon: [String, Function, Object],
29969
30151
  iconColor: String,
29970
- iconSize: [Number, String],
29971
- iconSizes: {
29972
- type: Array,
29973
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
29974
- },
29975
30152
  loading: Boolean,
29976
30153
  opacity: [Number, String],
29977
30154
  readonly: Boolean,
@@ -29991,6 +30168,7 @@
29991
30168
  ...makeBorderProps(),
29992
30169
  ...makeComponentProps(),
29993
30170
  ...makeElevationProps(),
30171
+ ...makeIconSizeProps(),
29994
30172
  ...makeRoundedProps(),
29995
30173
  ...makeTagProps({
29996
30174
  tag: 'button'
@@ -30045,7 +30223,6 @@
30045
30223
  })()
30046
30224
  }));
30047
30225
  const btnSizeMap = new Map(props.sizes);
30048
- const iconSizeMap = new Map(props.iconSizes);
30049
30226
  function onClick() {
30050
30227
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
30051
30228
  isActive.value = !isActive.value;
@@ -30057,12 +30234,12 @@
30057
30234
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
30058
30235
  const btnHeight = props.height ?? btnSize;
30059
30236
  const btnWidth = props.width ?? btnSize;
30060
- const _iconSize = props.iconSize;
30061
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
30062
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30237
+ const {
30238
+ iconSize
30239
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
30063
30240
  const iconProps = {
30064
30241
  icon,
30065
- size: iconSize,
30242
+ size: iconSize.value,
30066
30243
  iconColor: props.iconColor,
30067
30244
  opacity: props.opacity
30068
30245
  };
@@ -30105,7 +30282,7 @@
30105
30282
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30106
30283
  "indeterminate": "disable-shrink",
30107
30284
  "width": "2",
30108
- "size": iconSize
30285
+ "size": iconSize.value
30109
30286
  }, null)])]
30110
30287
  });
30111
30288
  });
@@ -32015,7 +32192,7 @@
32015
32192
  };
32016
32193
  });
32017
32194
  }
32018
- const version$1 = "3.8.6-master.2025-05-26";
32195
+ const version$1 = "3.8.7-dev.2025-05-27";
32019
32196
  createVuetify$1.version = version$1;
32020
32197
 
32021
32198
  // Vue's inject() can only be used in setup
@@ -32313,7 +32490,7 @@
32313
32490
 
32314
32491
  /* eslint-disable local-rules/sort-imports */
32315
32492
 
32316
- const version = "3.8.6-master.2025-05-26";
32493
+ const version = "3.8.7-dev.2025-05-27";
32317
32494
 
32318
32495
  /* eslint-disable local-rules/sort-imports */
32319
32496