@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
@@ -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
  */
@@ -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)
@@ -5555,8 +5630,8 @@
5555
5630
  window.clearTimeout(element._ripple.showTimer);
5556
5631
  }
5557
5632
  let keyboardRipple = false;
5558
- function keyboardRippleShow(e) {
5559
- if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
5633
+ function keyboardRippleShow(e, keys) {
5634
+ if (!keyboardRipple && keys.includes(e.keyCode)) {
5560
5635
  keyboardRipple = true;
5561
5636
  rippleShow(e);
5562
5637
  }
@@ -5584,9 +5659,12 @@
5584
5659
  el._ripple.enabled = enabled;
5585
5660
  el._ripple.centered = modifiers.center;
5586
5661
  el._ripple.circle = modifiers.circle;
5587
- if (isObject(value) && value.class) {
5588
- el._ripple.class = value.class;
5662
+ const bindingValue = isObject(value) ? value : {};
5663
+ if (bindingValue.class) {
5664
+ el._ripple.class = bindingValue.class;
5589
5665
  }
5666
+ const allowedKeys = bindingValue.keys ?? [keyCodes.enter, keyCodes.space];
5667
+ el._ripple.keyDownHandler = e => keyboardRippleShow(e, allowedKeys);
5590
5668
  if (enabled && !wasEnabled) {
5591
5669
  if (modifiers.stop) {
5592
5670
  el.addEventListener('touchstart', rippleStop, {
@@ -5608,7 +5686,7 @@
5608
5686
  el.addEventListener('mousedown', rippleShow);
5609
5687
  el.addEventListener('mouseup', rippleHide);
5610
5688
  el.addEventListener('mouseleave', rippleHide);
5611
- el.addEventListener('keydown', keyboardRippleShow);
5689
+ el.addEventListener('keydown', e => keyboardRippleShow(e, allowedKeys));
5612
5690
  el.addEventListener('keyup', keyboardRippleHide);
5613
5691
  el.addEventListener('blur', focusRippleHide);
5614
5692
 
@@ -5628,7 +5706,9 @@
5628
5706
  el.removeEventListener('touchcancel', rippleHide);
5629
5707
  el.removeEventListener('mouseup', rippleHide);
5630
5708
  el.removeEventListener('mouseleave', rippleHide);
5631
- el.removeEventListener('keydown', keyboardRippleShow);
5709
+ if (el._ripple?.keyDownHandler) {
5710
+ el.removeEventListener('keydown', el._ripple.keyDownHandler);
5711
+ }
5632
5712
  el.removeEventListener('keyup', keyboardRippleHide);
5633
5713
  el.removeEventListener('dragstart', rippleHide);
5634
5714
  el.removeEventListener('blur', focusRippleHide);
@@ -5637,8 +5717,8 @@
5637
5717
  updateRipple(el, binding, false);
5638
5718
  }
5639
5719
  function unmounted$4(el) {
5640
- delete el._ripple;
5641
5720
  removeListeners(el);
5721
+ delete el._ripple;
5642
5722
  }
5643
5723
  function updated$1(el, binding) {
5644
5724
  if (binding.value === binding.oldValue) {
@@ -5911,6 +5991,31 @@
5911
5991
  // Utilities
5912
5992
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5913
5993
 
5994
+ // Utilities
5995
+
5996
+ // Types
5997
+
5998
+ // Types
5999
+
6000
+ // Composables
6001
+ const makeIconSizeProps = propsFactory({
6002
+ iconSize: [Number, String],
6003
+ iconSizes: {
6004
+ type: Array,
6005
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
6006
+ }
6007
+ }, 'iconSize');
6008
+ function useIconSizes(props, fallback) {
6009
+ const iconSize = vue.computed(() => {
6010
+ const iconSizeMap = new Map(props.iconSizes);
6011
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
6012
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
6013
+ });
6014
+ return {
6015
+ iconSize
6016
+ };
6017
+ }
6018
+
5914
6019
  // Types
5915
6020
 
5916
6021
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5950,6 +6055,7 @@
5950
6055
  ...makeDensityProps(),
5951
6056
  ...makeDimensionProps(),
5952
6057
  ...makeElevationProps(),
6058
+ ...makeIconSizeProps(),
5953
6059
  ...makeLocationProps(),
5954
6060
  ...makePositionProps(),
5955
6061
  ...makeRoundedProps(),
@@ -5977,6 +6083,9 @@
5977
6083
  if (!props.type) return props.icon;
5978
6084
  return props.icon ?? `$${props.type}`;
5979
6085
  });
6086
+ const {
6087
+ iconSize
6088
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5980
6089
  const {
5981
6090
  themeClasses
5982
6091
  } = provideTheme(props);
@@ -6024,6 +6133,11 @@
6024
6133
  const hasPrepend = !!(slots.prepend || icon.value);
6025
6134
  const hasTitle = !!(slots.title || props.title);
6026
6135
  const hasClose = !!(slots.close || props.closable);
6136
+ const iconProps = {
6137
+ density: props.density,
6138
+ icon: icon.value,
6139
+ size: iconSize.value
6140
+ };
6027
6141
  return isActive.value && vue.createVNode(props.tag, {
6028
6142
  "class": vue.normalizeClass(['v-alert', props.border && {
6029
6143
  'v-alert--border': !!props.border,
@@ -6041,19 +6155,14 @@
6041
6155
  }, null), hasPrepend && vue.createElementVNode("div", {
6042
6156
  "key": "prepend",
6043
6157
  "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, {
6158
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6159
+ "key": "prepend-icon"
6160
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6050
6161
  "key": "prepend-defaults",
6051
6162
  "disabled": !icon.value,
6052
6163
  "defaults": {
6053
6164
  VIcon: {
6054
- density: props.density,
6055
- icon: icon.value,
6056
- size: props.prominent ? 44 : 28
6165
+ ...iconProps
6057
6166
  }
6058
6167
  }
6059
6168
  }, slots.prepend)]), vue.createElementVNode("div", {
@@ -7578,6 +7687,7 @@
7578
7687
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
7579
7688
  const makeVSlideGroupProps = propsFactory({
7580
7689
  centerActive: Boolean,
7690
+ contentClass: null,
7581
7691
  direction: {
7582
7692
  type: String,
7583
7693
  default: 'horizontal'
@@ -7890,7 +8000,7 @@
7890
8000
  })]), vue.createElementVNode("div", {
7891
8001
  "key": "container",
7892
8002
  "ref": containerRef,
7893
- "class": "v-slide-group__container",
8003
+ "class": vue.normalizeClass(['v-slide-group__container', props.contentClass]),
7894
8004
  "onScroll": onScroll
7895
8005
  }, [vue.createElementVNode("div", {
7896
8006
  "ref": contentRef,
@@ -8252,16 +8362,85 @@
8252
8362
  }
8253
8363
  });
8254
8364
 
8365
+ const makeVDividerProps = propsFactory({
8366
+ color: String,
8367
+ inset: Boolean,
8368
+ length: [Number, String],
8369
+ opacity: [Number, String],
8370
+ thickness: [Number, String],
8371
+ vertical: Boolean,
8372
+ ...makeComponentProps(),
8373
+ ...makeThemeProps()
8374
+ }, 'VDivider');
8375
+ const VDivider = genericComponent()({
8376
+ name: 'VDivider',
8377
+ props: makeVDividerProps(),
8378
+ setup(props, _ref) {
8379
+ let {
8380
+ attrs,
8381
+ slots
8382
+ } = _ref;
8383
+ const {
8384
+ themeClasses
8385
+ } = provideTheme(props);
8386
+ const {
8387
+ textColorClasses,
8388
+ textColorStyles
8389
+ } = useTextColor(() => props.color);
8390
+ const dividerStyles = vue.computed(() => {
8391
+ const styles = {};
8392
+ if (props.length) {
8393
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8394
+ }
8395
+ if (props.thickness) {
8396
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8397
+ }
8398
+ return styles;
8399
+ });
8400
+ useRender(() => {
8401
+ const divider = vue.createElementVNode("hr", {
8402
+ "class": vue.normalizeClass([{
8403
+ 'v-divider': true,
8404
+ 'v-divider--inset': props.inset,
8405
+ 'v-divider--vertical': props.vertical
8406
+ }, themeClasses.value, textColorClasses.value, props.class]),
8407
+ "style": vue.normalizeStyle([dividerStyles.value, textColorStyles.value, {
8408
+ '--v-border-opacity': props.opacity
8409
+ }, props.style]),
8410
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8411
+ "role": `${attrs.role || 'separator'}`
8412
+ }, null);
8413
+ if (!slots.default) return divider;
8414
+ return vue.createElementVNode("div", {
8415
+ "class": vue.normalizeClass(['v-divider__wrapper', {
8416
+ 'v-divider__wrapper--vertical': props.vertical,
8417
+ 'v-divider__wrapper--inset': props.inset
8418
+ }])
8419
+ }, [divider, vue.createElementVNode("div", {
8420
+ "class": "v-divider__content"
8421
+ }, [slots.default()]), divider]);
8422
+ });
8423
+ return {};
8424
+ }
8425
+ });
8426
+
8255
8427
  // Utilities
8256
8428
 
8257
8429
  // List
8258
8430
  const ListKey = Symbol.for('vuetify:list');
8259
8431
  function createList() {
8432
+ let {
8433
+ filterable
8434
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
8435
+ filterable: false
8436
+ };
8260
8437
  const parent = vue.inject(ListKey, {
8438
+ filterable: false,
8261
8439
  hasPrepend: vue.shallowRef(false),
8262
8440
  updateHasPrepend: () => null
8263
8441
  });
8264
8442
  const data = {
8443
+ filterable: parent.filterable || filterable,
8265
8444
  hasPrepend: vue.shallowRef(false),
8266
8445
  updateHasPrepend: value => {
8267
8446
  if (value) data.hasPrepend.value = value;
@@ -9213,6 +9392,9 @@
9213
9392
  roundedClasses
9214
9393
  } = useRounded(roundedProps);
9215
9394
  const lineClasses = vue.toRef(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
9395
+ const rippleOptions = vue.toRef(() => props.ripple !== undefined && !!props.ripple && list?.filterable ? {
9396
+ keys: [keyCodes.enter]
9397
+ } : props.ripple);
9216
9398
  const slotProps = vue.computed(() => ({
9217
9399
  isActive: isActive.value,
9218
9400
  select,
@@ -9237,8 +9419,9 @@
9237
9419
  function onKeyDown(e) {
9238
9420
  const target = e.target;
9239
9421
  if (['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
9240
- if (e.key === 'Enter' || e.key === ' ') {
9422
+ if (e.key === 'Enter' || e.key === ' ' && !list?.filterable) {
9241
9423
  e.preventDefault();
9424
+ e.stopPropagation();
9242
9425
  e.target.dispatchEvent(new MouseEvent('click', e));
9243
9426
  }
9244
9427
  }
@@ -9348,7 +9531,7 @@
9348
9531
  }), vue.createElementVNode("div", {
9349
9532
  "class": "v-list-item__spacer"
9350
9533
  }, null)])]
9351
- }), [[Ripple, isClickable.value && props.ripple]]);
9534
+ }), [[Ripple, isClickable.value && rippleOptions.value]]);
9352
9535
  });
9353
9536
  return {
9354
9537
  activate,
@@ -9403,68 +9586,6 @@
9403
9586
  }
9404
9587
  });
9405
9588
 
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
9589
  // Types
9469
9590
 
9470
9591
  const makeVListChildrenProps = propsFactory({
@@ -9733,6 +9854,7 @@
9733
9854
  activeClass: String,
9734
9855
  bgColor: String,
9735
9856
  disabled: Boolean,
9857
+ filterable: Boolean,
9736
9858
  expandIcon: IconValue,
9737
9859
  collapseIcon: IconValue,
9738
9860
  lines: {
@@ -9816,7 +9938,9 @@
9816
9938
  const activeColor = vue.toRef(() => props.activeColor);
9817
9939
  const baseColor = vue.toRef(() => props.baseColor);
9818
9940
  const color = vue.toRef(() => props.color);
9819
- createList();
9941
+ createList({
9942
+ filterable: props.filterable
9943
+ });
9820
9944
  provideDefaults({
9821
9945
  VListGroup: {
9822
9946
  activeColor,
@@ -12392,7 +12516,12 @@
12392
12516
  }
12393
12517
  function calculateOffset(index) {
12394
12518
  index = clamp(index, 0, items.value.length - 1);
12395
- return offsets[index] || 0;
12519
+ const whole = Math.floor(index);
12520
+ const fraction = index % 1;
12521
+ const next = whole + 1;
12522
+ const wholeOffset = offsets[whole] || 0;
12523
+ const nextOffset = offsets[next] || wholeOffset;
12524
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12396
12525
  }
12397
12526
  function calculateIndex(scrollTop) {
12398
12527
  return binaryClosest(offsets, scrollTop);
@@ -12746,6 +12875,7 @@
12746
12875
  },
12747
12876
  openOnClear: Boolean,
12748
12877
  itemColor: String,
12878
+ noAutoScroll: Boolean,
12749
12879
  ...makeItemsProps({
12750
12880
  itemChildren: false
12751
12881
  })
@@ -12960,7 +13090,7 @@
12960
13090
  vue.watch(menu, () => {
12961
13091
  if (!props.hideSelected && menu.value && model.value.length) {
12962
13092
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
12963
- IN_BROWSER && window.requestAnimationFrame(() => {
13093
+ IN_BROWSER && !props.noAutoScroll && window.requestAnimationFrame(() => {
12964
13094
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
12965
13095
  });
12966
13096
  }
@@ -13052,6 +13182,22 @@
13052
13182
  key: item.value,
13053
13183
  onClick: () => select(item, null)
13054
13184
  });
13185
+ if (item.raw.type === 'divider') {
13186
+ return slots.divider?.({
13187
+ props: item.raw,
13188
+ index
13189
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13190
+ "key": `divider-${index}`
13191
+ }), null);
13192
+ }
13193
+ if (item.raw.type === 'subheader') {
13194
+ return slots.subheader?.({
13195
+ props: item.raw,
13196
+ index
13197
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13198
+ "key": `subheader-${index}`
13199
+ }), null);
13200
+ }
13055
13201
  return slots.item?.({
13056
13202
  item,
13057
13203
  index,
@@ -13212,6 +13358,9 @@
13212
13358
  let match = -1;
13213
13359
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13214
13360
  if (typeof item === 'object') {
13361
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13362
+ continue;
13363
+ }
13215
13364
  const filterKeys = keys || Object.keys(transformed);
13216
13365
  for (const key of filterKeys) {
13217
13366
  const value = getPropertyFromItem(transformed, key);
@@ -13414,7 +13563,7 @@
13414
13563
  menu.value = !menu.value;
13415
13564
  }
13416
13565
  function onListKeydown(e) {
13417
- if (e.key !== ' ' && checkPrintable(e)) {
13566
+ if (checkPrintable(e) || e.key === 'Backspace') {
13418
13567
  vTextFieldRef.value?.focus();
13419
13568
  }
13420
13569
  }
@@ -13619,6 +13768,7 @@
13619
13768
  }, props.menuProps), {
13620
13769
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
13621
13770
  "ref": listRef,
13771
+ "filterable": true,
13622
13772
  "selected": selectedValues.value,
13623
13773
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
13624
13774
  "onMousedown": e => e.preventDefault(),
@@ -13650,6 +13800,22 @@
13650
13800
  active: highlightFirst.value && index === 0 ? true : undefined,
13651
13801
  onClick: () => select(item, null)
13652
13802
  });
13803
+ if (item.raw.type === 'divider') {
13804
+ return slots.divider?.({
13805
+ props: item.raw,
13806
+ index
13807
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13808
+ "key": `divider-${index}`
13809
+ }), null);
13810
+ }
13811
+ if (item.raw.type === 'subheader') {
13812
+ return slots.subheader?.({
13813
+ props: item.raw,
13814
+ index
13815
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13816
+ "key": `subheader-${index}`
13817
+ }), null);
13818
+ }
13653
13819
  return slots.item?.({
13654
13820
  item,
13655
13821
  index,
@@ -17245,13 +17411,13 @@
17245
17411
  return null;
17246
17412
  }
17247
17413
  const sundayJanuarySecond2000 = new Date(2000, 0, 2);
17248
- function getWeekdays(locale, firstDayOfWeek) {
17414
+ function getWeekdays(locale, firstDayOfWeek, weekdayFormat) {
17249
17415
  const daysFromSunday = firstDayOfWeek ?? weekInfo(locale)?.firstDay ?? 0;
17250
17416
  return createRange(7).map(i => {
17251
17417
  const weekday = new Date(sundayJanuarySecond2000);
17252
17418
  weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
17253
17419
  return new Intl.DateTimeFormat(locale, {
17254
- weekday: 'narrow'
17420
+ weekday: weekdayFormat ?? 'narrow'
17255
17421
  }).format(weekday);
17256
17422
  });
17257
17423
  }
@@ -17715,9 +17881,9 @@
17715
17881
  getDiff(date, comparing, unit) {
17716
17882
  return getDiff(date, comparing, unit);
17717
17883
  }
17718
- getWeekdays(firstDayOfWeek) {
17884
+ getWeekdays(firstDayOfWeek, weekdayFormat) {
17719
17885
  const firstDay = firstDayOfWeek !== undefined ? Number(firstDayOfWeek) : undefined;
17720
- return getWeekdays(this.locale, firstDay);
17886
+ return getWeekdays(this.locale, firstDay, weekdayFormat);
17721
17887
  }
17722
17888
  getYear(date) {
17723
17889
  return getYear(date);
@@ -18060,6 +18226,7 @@
18060
18226
  _search.value = val ?? '';
18061
18227
  if (!props.multiple && !hasSelectionSlot.value) {
18062
18228
  model.value = [transformItem$3(props, val)];
18229
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
18063
18230
  }
18064
18231
  if (val && props.multiple && props.delimiters?.length) {
18065
18232
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18140,7 +18307,7 @@
18140
18307
  menu.value = !menu.value;
18141
18308
  }
18142
18309
  function onListKeydown(e) {
18143
- if (e.key !== ' ' && checkPrintable(e)) {
18310
+ if (checkPrintable(e) || e.key === 'Backspace') {
18144
18311
  vTextFieldRef.value?.focus();
18145
18312
  }
18146
18313
  }
@@ -18345,6 +18512,7 @@
18345
18512
  }, props.menuProps), {
18346
18513
  default: () => [hasList && vue.createVNode(VList, vue.mergeProps({
18347
18514
  "ref": listRef,
18515
+ "filterable": true,
18348
18516
  "selected": selectedValues.value,
18349
18517
  "selectStrategy": props.multiple ? 'independent' : 'single-independent',
18350
18518
  "onMousedown": e => e.preventDefault(),
@@ -18376,6 +18544,22 @@
18376
18544
  active: highlightFirst.value && index === 0 ? true : undefined,
18377
18545
  onClick: () => select(item, null)
18378
18546
  });
18547
+ if (item.raw.type === 'divider') {
18548
+ return slots.divider?.({
18549
+ props: item.raw,
18550
+ index
18551
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18552
+ "key": `divider-${index}`
18553
+ }), null);
18554
+ }
18555
+ if (item.raw.type === 'subheader') {
18556
+ return slots.subheader?.({
18557
+ props: item.raw,
18558
+ index
18559
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18560
+ "key": `subheader-${index}`
18561
+ }), null);
18562
+ }
18379
18563
  return slots.item?.({
18380
18564
  item,
18381
18565
  index,
@@ -20255,6 +20439,7 @@
20255
20439
  color: String,
20256
20440
  disableSort: Boolean,
20257
20441
  fixedHeader: Boolean,
20442
+ lastFixed: Boolean,
20258
20443
  multiSort: Boolean,
20259
20444
  sortAscIcon: {
20260
20445
  type: IconValue,
@@ -20301,10 +20486,11 @@
20301
20486
  loaderClasses
20302
20487
  } = useLoader(props);
20303
20488
  function getFixedStyles(column, y) {
20304
- if (!(props.sticky || props.fixedHeader) && !column.fixed) return undefined;
20489
+ if (!(props.sticky || props.fixedHeader) && !(column.fixed || column.lastFixed)) return undefined;
20305
20490
  return {
20306
20491
  position: 'sticky',
20307
- left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
20492
+ left: column.fixed || column.lastFixed ? convertToUnit(column.fixedOffset) : undefined,
20493
+ right: column.lastFixed ? convertToUnit(column.fixedOffset ?? 0) : undefined,
20308
20494
  top: props.sticky || props.fixedHeader ? `calc(var(--v-table-header-height) * ${y})` : undefined
20309
20495
  };
20310
20496
  }
@@ -22019,7 +22205,8 @@
22019
22205
  firstDayOfWeek: {
22020
22206
  type: [Number, String],
22021
22207
  default: undefined
22022
- }
22208
+ },
22209
+ weekdayFormat: String
22023
22210
  }, 'calendar');
22024
22211
  function useCalendar(props) {
22025
22212
  const adapter = useDate();
@@ -22267,7 +22454,7 @@
22267
22454
  "ref": daysRef,
22268
22455
  "key": daysInMonth.value[0].date?.toString(),
22269
22456
  "class": "v-date-picker-month__days"
22270
- }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => vue.createElementVNode("div", {
22457
+ }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek, props.weekdayFormat).map(weekDay => vue.createElementVNode("div", {
22271
22458
  "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
22272
22459
  }, [weekDay])), daysInMonth.value.map((item, i) => {
22273
22460
  const slotProps = {
@@ -24798,6 +24985,10 @@
24798
24985
  type: Number,
24799
24986
  default: 0
24800
24987
  },
24988
+ minFractionDigits: {
24989
+ type: Number,
24990
+ default: null
24991
+ },
24801
24992
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24802
24993
  }, 'VNumberInput');
24803
24994
  const VNumberInput = genericComponent()({
@@ -24828,9 +25019,19 @@
24828
25019
  } = useFocus(props);
24829
25020
  function correctPrecision(val) {
24830
25021
  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;
25022
+ if (precision == null) {
25023
+ return String(val);
25024
+ }
25025
+ let fixed = val.toFixed(precision);
25026
+ if (isFocused.value) {
25027
+ return Number(fixed).toString(); // trim zeros
25028
+ }
25029
+ if ((props.minFractionDigits ?? precision) < precision) {
25030
+ const trimLimit = precision - props.minFractionDigits;
25031
+ const [baseDigits, fractionDigits] = fixed.split('.');
25032
+ fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
25033
+ }
25034
+ return fixed;
24834
25035
  }
24835
25036
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24836
25037
  const _inputText = vue.shallowRef(null);
@@ -24889,6 +25090,7 @@
24889
25090
  }
24890
25091
  };
24891
25092
  vue.watch(() => props.precision, () => formatInputValue());
25093
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
24892
25094
  vue.onMounted(() => {
24893
25095
  clampModel();
24894
25096
  });
@@ -24998,7 +25200,7 @@
24998
25200
  inputText.value = null;
24999
25201
  return;
25000
25202
  }
25001
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25203
+ inputText.value = correctPrecision(model.value);
25002
25204
  }
25003
25205
  function trimDecimalZeros() {
25004
25206
  if (controlsDisabled.value) return;
@@ -25258,9 +25460,10 @@
25258
25460
  e.preventDefault();
25259
25461
  e.stopPropagation();
25260
25462
  const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
25463
+ const finalIndex = clipboardText.length - 1 === -1 ? index : clipboardText.length - 1;
25261
25464
  if (isValidNumber(clipboardText)) return;
25262
25465
  model.value = clipboardText.split('');
25263
- inputRef.value?.[index].blur();
25466
+ inputRef.value?.[finalIndex].focus();
25264
25467
  }
25265
25468
  function reset() {
25266
25469
  model.value = [];
@@ -29967,11 +30170,6 @@
29967
30170
  hideOverlay: Boolean,
29968
30171
  icon: [String, Function, Object],
29969
30172
  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
30173
  loading: Boolean,
29976
30174
  opacity: [Number, String],
29977
30175
  readonly: Boolean,
@@ -29991,6 +30189,7 @@
29991
30189
  ...makeBorderProps(),
29992
30190
  ...makeComponentProps(),
29993
30191
  ...makeElevationProps(),
30192
+ ...makeIconSizeProps(),
29994
30193
  ...makeRoundedProps(),
29995
30194
  ...makeTagProps({
29996
30195
  tag: 'button'
@@ -30045,7 +30244,6 @@
30045
30244
  })()
30046
30245
  }));
30047
30246
  const btnSizeMap = new Map(props.sizes);
30048
- const iconSizeMap = new Map(props.iconSizes);
30049
30247
  function onClick() {
30050
30248
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
30051
30249
  isActive.value = !isActive.value;
@@ -30057,12 +30255,12 @@
30057
30255
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
30058
30256
  const btnHeight = props.height ?? btnSize;
30059
30257
  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;
30258
+ const {
30259
+ iconSize
30260
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
30063
30261
  const iconProps = {
30064
30262
  icon,
30065
- size: iconSize,
30263
+ size: iconSize.value,
30066
30264
  iconColor: props.iconColor,
30067
30265
  opacity: props.opacity
30068
30266
  };
@@ -30105,7 +30303,7 @@
30105
30303
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30106
30304
  "indeterminate": "disable-shrink",
30107
30305
  "width": "2",
30108
- "size": iconSize
30306
+ "size": iconSize.value
30109
30307
  }, null)])]
30110
30308
  });
30111
30309
  });
@@ -32015,7 +32213,7 @@
32015
32213
  };
32016
32214
  });
32017
32215
  }
32018
- const version$1 = "3.8.6-master.2025-05-26";
32216
+ const version$1 = "3.8.7-dev.2025-05-30";
32019
32217
  createVuetify$1.version = version$1;
32020
32218
 
32021
32219
  // Vue's inject() can only be used in setup
@@ -32313,7 +32511,7 @@
32313
32511
 
32314
32512
  /* eslint-disable local-rules/sort-imports */
32315
32513
 
32316
- const version = "3.8.6-master.2025-05-26";
32514
+ const version = "3.8.7-dev.2025-05-30";
32317
32515
 
32318
32516
  /* eslint-disable local-rules/sort-imports */
32319
32517