@vuetify/nightly 3.8.5-master.2025-05-20 → 3.8.6-dev.2025-05-21

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 (90) hide show
  1. package/CHANGELOG.md +21 -14
  2. package/dist/json/attributes.json +1331 -1311
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +192 -192
  5. package/dist/json/tags.json +5 -0
  6. package/dist/json/web-types.json +2610 -2471
  7. package/dist/vuetify-labs.cjs +288 -117
  8. package/dist/vuetify-labs.css +3866 -3838
  9. package/dist/vuetify-labs.d.ts +1490 -1352
  10. package/dist/vuetify-labs.esm.js +289 -118
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +288 -117
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +282 -106
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +3130 -3102
  17. package/dist/vuetify.d.ts +659 -519
  18. package/dist/vuetify.esm.js +283 -107
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +282 -106
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1188 -1178
  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 +14 -9
  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 +120 -96
  31. package/lib/components/VAutocomplete/VAutocomplete.js +18 -1
  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/VCombobox/VCombobox.d.ts +120 -96
  41. package/lib/components/VCombobox/VCombobox.js +19 -1
  42. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  43. package/lib/components/VField/VField.d.ts +3 -3
  44. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  45. package/lib/components/VInput/VInput.d.ts +4 -4
  46. package/lib/components/VList/VListChildren.js.map +1 -1
  47. package/lib/components/VNumberInput/VNumberInput.d.ts +103 -89
  48. package/lib/components/VNumberInput/VNumberInput.js +19 -4
  49. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  50. package/lib/components/VOverlay/VOverlay.css +1 -1
  51. package/lib/components/VOverlay/_variables.scss +1 -1
  52. package/lib/components/VRadioGroup/VRadioGroup.d.ts +3 -3
  53. package/lib/components/VRangeSlider/VRangeSlider.d.ts +3 -3
  54. package/lib/components/VSelect/VSelect.d.ts +120 -96
  55. package/lib/components/VSelect/VSelect.js +18 -1
  56. package/lib/components/VSelect/VSelect.js.map +1 -1
  57. package/lib/components/VSlider/VSlider.d.ts +3 -3
  58. package/lib/components/VSwitch/VSwitch.d.ts +3 -3
  59. package/lib/components/VTextField/VTextField.d.ts +27 -27
  60. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  61. package/lib/composables/calendar.d.ts +1 -0
  62. package/lib/composables/calendar.js.map +1 -1
  63. package/lib/composables/date/index.d.ts +1 -0
  64. package/lib/composables/date/index.js +1 -0
  65. package/lib/composables/date/index.js.map +1 -1
  66. package/lib/composables/filter.js +3 -0
  67. package/lib/composables/filter.js.map +1 -1
  68. package/lib/composables/iconSizes.d.ts +28 -0
  69. package/lib/composables/iconSizes.js +23 -0
  70. package/lib/composables/iconSizes.js.map +1 -0
  71. package/lib/composables/theme.d.ts +6 -1
  72. package/lib/composables/theme.js +94 -26
  73. package/lib/composables/theme.js.map +1 -1
  74. package/lib/composables/virtual.js +6 -1
  75. package/lib/composables/virtual.js.map +1 -1
  76. package/lib/entry-bundler.js +1 -1
  77. package/lib/entry-bundler.js.map +1 -1
  78. package/lib/framework.d.ts +74 -69
  79. package/lib/framework.js +1 -1
  80. package/lib/framework.js.map +1 -1
  81. package/lib/labs/VColorInput/VColorInput.d.ts +3 -3
  82. package/lib/labs/VDateInput/VDateInput.d.ts +87 -87
  83. package/lib/labs/VFileUpload/VFileUpload.d.ts +3 -3
  84. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  85. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  86. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  87. package/lib/util/globals.d.ts +1 -0
  88. package/lib/util/globals.js +1 -0
  89. package/lib/util/globals.js.map +1 -1
  90. package/package.json +3 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.5-master.2025-05-20
2
+ * Vuetify v3.8.6-dev.2025-05-21
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"); }
@@ -2299,6 +2300,7 @@
2299
2300
  function genDefaults$2() {
2300
2301
  return {
2301
2302
  defaultTheme: 'light',
2303
+ prefix: 'v-',
2302
2304
  variations: {
2303
2305
  colors: [],
2304
2306
  lighten: 0,
@@ -2380,7 +2382,10 @@
2380
2382
  }
2381
2383
  }
2382
2384
  },
2383
- stylesheetId: 'vuetify-theme-stylesheet'
2385
+ stylesheetId: 'vuetify-theme-stylesheet',
2386
+ scoped: false,
2387
+ unimportant: false,
2388
+ utilities: true
2384
2389
  };
2385
2390
  }
2386
2391
  function parseThemeOptions() {
@@ -2403,21 +2408,21 @@
2403
2408
  function createCssClass(lines, selector, content, scope) {
2404
2409
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2405
2410
  }
2406
- function genCssVariables(theme) {
2411
+ function genCssVariables(theme, prefix) {
2407
2412
  const lightOverlay = theme.dark ? 2 : 1;
2408
2413
  const darkOverlay = theme.dark ? 1 : 2;
2409
2414
  const variables = [];
2410
2415
  for (const [key, value] of Object.entries(theme.colors)) {
2411
2416
  const rgb = parseColor(value);
2412
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2417
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2413
2418
  if (!key.startsWith('on-')) {
2414
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2419
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2415
2420
  }
2416
2421
  }
2417
2422
  for (const [key, value] of Object.entries(theme.variables)) {
2418
2423
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2419
2424
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2420
- variables.push(`--v-${key}: ${rgb ?? value}`);
2425
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2421
2426
  }
2422
2427
  return variables;
2423
2428
  }
@@ -2461,7 +2466,8 @@
2461
2466
  const scopeSelector = `:where(${scope})`;
2462
2467
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2463
2468
  }
2464
- function upsertStyles(styleEl, styles) {
2469
+ function upsertStyles(id, cspNonce, styles) {
2470
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2465
2471
  if (!styleEl) return;
2466
2472
  styleEl.innerHTML = styles;
2467
2473
  }
@@ -2481,8 +2487,17 @@
2481
2487
  // Composables
2482
2488
  function createTheme(options) {
2483
2489
  const parsedOptions = parseThemeOptions(options);
2484
- const name = vue.shallowRef(parsedOptions.defaultTheme);
2490
+ const _name = vue.shallowRef(parsedOptions.defaultTheme);
2485
2491
  const themes = vue.ref(parsedOptions.themes);
2492
+ const systemName = vue.shallowRef('light');
2493
+ const name = vue.computed({
2494
+ get() {
2495
+ return _name.value === 'system' ? systemName.value : _name.value;
2496
+ },
2497
+ set(val) {
2498
+ _name.value = val;
2499
+ }
2500
+ });
2486
2501
  const computedThemes = vue.computed(() => {
2487
2502
  const acc = {};
2488
2503
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2503,28 +2518,49 @@
2503
2518
  const current = vue.toRef(() => computedThemes.value[name.value]);
2504
2519
  const styles = vue.computed(() => {
2505
2520
  const lines = [];
2521
+ const important = parsedOptions.unimportant ? '' : ' !important';
2522
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2506
2523
  if (current.value?.dark) {
2507
2524
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2508
2525
  }
2509
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2526
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2510
2527
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2511
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2512
- }
2513
- const bgLines = [];
2514
- const fgLines = [];
2515
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2516
- for (const key of colors) {
2517
- if (key.startsWith('on-')) {
2518
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2519
- } else {
2520
- 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);
2521
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2522
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2528
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2529
+ }
2530
+ if (parsedOptions.utilities) {
2531
+ const bgLines = [];
2532
+ const fgLines = [];
2533
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2534
+ for (const key of colors) {
2535
+ if (key.startsWith('on-')) {
2536
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2537
+ } else {
2538
+ 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);
2539
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2540
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2541
+ }
2523
2542
  }
2543
+ lines.push(...bgLines, ...fgLines);
2524
2544
  }
2525
- lines.push(...bgLines, ...fgLines);
2526
2545
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2527
2546
  });
2547
+ const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2548
+ const themeNames = vue.toRef(() => Object.keys(computedThemes.value));
2549
+ if (SUPPORTS_MATCH_MEDIA) {
2550
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2551
+ function updateSystemName() {
2552
+ systemName.value = media.matches ? 'dark' : 'light';
2553
+ }
2554
+ updateSystemName();
2555
+ media.addEventListener('change', updateSystemName, {
2556
+ passive: true
2557
+ });
2558
+ if (vue.getCurrentScope()) {
2559
+ vue.onScopeDispose(() => {
2560
+ media.removeEventListener('change', updateSystemName);
2561
+ });
2562
+ }
2563
+ }
2528
2564
  function install(app) {
2529
2565
  if (parsedOptions.isDisabled) return;
2530
2566
  const head = app._context.provides.usehead;
@@ -2562,22 +2598,55 @@
2562
2598
  updateStyles();
2563
2599
  }
2564
2600
  function updateStyles() {
2565
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2601
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2566
2602
  }
2567
2603
  }
2568
2604
  }
2569
- const themeClasses = vue.toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2605
+ function change(themeName) {
2606
+ if (!themeNames.value.includes(themeName)) {
2607
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2608
+ return;
2609
+ }
2610
+ name.value = themeName;
2611
+ }
2612
+ function cycle() {
2613
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2614
+ const currentIndex = themeArray.indexOf(name.value);
2615
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2616
+ change(themeArray[nextIndex]);
2617
+ }
2618
+ function toggle() {
2619
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2620
+ cycle(themeArray);
2621
+ }
2622
+ const globalName = new Proxy(name, {
2623
+ get(target, prop) {
2624
+ return target[prop];
2625
+ },
2626
+ set(target, prop, val) {
2627
+ if (prop === 'value') {
2628
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2629
+ }
2630
+ // @ts-expect-error
2631
+ target[prop] = val;
2632
+ return true;
2633
+ }
2634
+ });
2570
2635
  return {
2571
2636
  install,
2637
+ change,
2638
+ cycle,
2639
+ toggle,
2572
2640
  isDisabled: parsedOptions.isDisabled,
2573
2641
  name,
2574
2642
  themes,
2575
2643
  current,
2576
2644
  computedThemes,
2645
+ prefix: parsedOptions.prefix,
2577
2646
  themeClasses,
2578
2647
  styles,
2579
2648
  global: {
2580
- name,
2649
+ name: globalName,
2581
2650
  current
2582
2651
  }
2583
2652
  };
@@ -2588,7 +2657,7 @@
2588
2657
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2589
2658
  const name = vue.toRef(() => props.theme ?? theme.name.value);
2590
2659
  const current = vue.toRef(() => theme.themes.value[name.value]);
2591
- const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2660
+ const themeClasses = vue.toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2592
2661
  const newTheme = {
2593
2662
  ...theme,
2594
2663
  name,
@@ -4135,9 +4204,15 @@
4135
4204
  };
4136
4205
  }
4137
4206
 
4207
+ // Types
4208
+
4138
4209
  const makeVBtnGroupProps = propsFactory({
4139
4210
  baseColor: String,
4140
4211
  divided: Boolean,
4212
+ direction: {
4213
+ type: String,
4214
+ default: 'horizontal'
4215
+ },
4141
4216
  ...makeBorderProps(),
4142
4217
  ...makeComponentProps(),
4143
4218
  ...makeDensityProps(),
@@ -4171,7 +4246,7 @@
4171
4246
  } = useRounded(props);
4172
4247
  provideDefaults({
4173
4248
  VBtn: {
4174
- height: 'auto',
4249
+ height: vue.toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4175
4250
  baseColor: vue.toRef(() => props.baseColor),
4176
4251
  color: vue.toRef(() => props.color),
4177
4252
  density: vue.toRef(() => props.density),
@@ -4181,7 +4256,7 @@
4181
4256
  });
4182
4257
  useRender(() => {
4183
4258
  return vue.createVNode(props.tag, {
4184
- "class": ['v-btn-group', {
4259
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4185
4260
  'v-btn-group--divided': props.divided
4186
4261
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4187
4262
  "style": props.style
@@ -5869,6 +5944,31 @@
5869
5944
  // Utilities
5870
5945
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5871
5946
 
5947
+ // Utilities
5948
+
5949
+ // Types
5950
+
5951
+ // Types
5952
+
5953
+ // Composables
5954
+ const makeIconSizeProps = propsFactory({
5955
+ iconSize: [Number, String],
5956
+ iconSizes: {
5957
+ type: Array,
5958
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
5959
+ }
5960
+ }, 'iconSize');
5961
+ function useIconSizes(props, fallback) {
5962
+ const iconSize = vue.computed(() => {
5963
+ const iconSizeMap = new Map(props.iconSizes);
5964
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
5965
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
5966
+ });
5967
+ return {
5968
+ iconSize
5969
+ };
5970
+ }
5971
+
5872
5972
  // Types
5873
5973
 
5874
5974
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5908,6 +6008,7 @@
5908
6008
  ...makeDensityProps(),
5909
6009
  ...makeDimensionProps(),
5910
6010
  ...makeElevationProps(),
6011
+ ...makeIconSizeProps(),
5911
6012
  ...makeLocationProps(),
5912
6013
  ...makePositionProps(),
5913
6014
  ...makeRoundedProps(),
@@ -5935,6 +6036,9 @@
5935
6036
  if (!props.type) return props.icon;
5936
6037
  return props.icon ?? `$${props.type}`;
5937
6038
  });
6039
+ const {
6040
+ iconSize
6041
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5938
6042
  const {
5939
6043
  themeClasses
5940
6044
  } = provideTheme(props);
@@ -5982,6 +6086,11 @@
5982
6086
  const hasPrepend = !!(slots.prepend || icon.value);
5983
6087
  const hasTitle = !!(slots.title || props.title);
5984
6088
  const hasClose = !!(slots.close || props.closable);
6089
+ const iconProps = {
6090
+ density: props.density,
6091
+ icon: icon.value,
6092
+ size: iconSize.value
6093
+ };
5985
6094
  return isActive.value && vue.createVNode(props.tag, {
5986
6095
  "class": ['v-alert', props.border && {
5987
6096
  'v-alert--border': !!props.border,
@@ -5999,19 +6108,14 @@
5999
6108
  }, null), hasPrepend && vue.createVNode("div", {
6000
6109
  "key": "prepend",
6001
6110
  "class": "v-alert__prepend"
6002
- }, [!slots.prepend ? vue.createVNode(VIcon, {
6003
- "key": "prepend-icon",
6004
- "density": props.density,
6005
- "icon": icon.value,
6006
- "size": props.prominent ? 44 : 28
6007
- }, null) : vue.createVNode(VDefaultsProvider, {
6111
+ }, [!slots.prepend ? vue.createVNode(VIcon, vue.mergeProps({
6112
+ "key": "prepend-icon"
6113
+ }, iconProps), null) : vue.createVNode(VDefaultsProvider, {
6008
6114
  "key": "prepend-defaults",
6009
6115
  "disabled": !icon.value,
6010
6116
  "defaults": {
6011
6117
  VIcon: {
6012
- density: props.density,
6013
- icon: icon.value,
6014
- size: props.prominent ? 44 : 28
6118
+ ...iconProps
6015
6119
  }
6016
6120
  }
6017
6121
  }, slots.prepend)]), vue.createVNode("div", {
@@ -8209,6 +8313,68 @@
8209
8313
  }
8210
8314
  });
8211
8315
 
8316
+ const makeVDividerProps = propsFactory({
8317
+ color: String,
8318
+ inset: Boolean,
8319
+ length: [Number, String],
8320
+ opacity: [Number, String],
8321
+ thickness: [Number, String],
8322
+ vertical: Boolean,
8323
+ ...makeComponentProps(),
8324
+ ...makeThemeProps()
8325
+ }, 'VDivider');
8326
+ const VDivider = genericComponent()({
8327
+ name: 'VDivider',
8328
+ props: makeVDividerProps(),
8329
+ setup(props, _ref) {
8330
+ let {
8331
+ attrs,
8332
+ slots
8333
+ } = _ref;
8334
+ const {
8335
+ themeClasses
8336
+ } = provideTheme(props);
8337
+ const {
8338
+ textColorClasses,
8339
+ textColorStyles
8340
+ } = useTextColor(() => props.color);
8341
+ const dividerStyles = vue.computed(() => {
8342
+ const styles = {};
8343
+ if (props.length) {
8344
+ styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
8345
+ }
8346
+ if (props.thickness) {
8347
+ styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
8348
+ }
8349
+ return styles;
8350
+ });
8351
+ useRender(() => {
8352
+ const divider = vue.createVNode("hr", {
8353
+ "class": [{
8354
+ 'v-divider': true,
8355
+ 'v-divider--inset': props.inset,
8356
+ 'v-divider--vertical': props.vertical
8357
+ }, themeClasses.value, textColorClasses.value, props.class],
8358
+ "style": [dividerStyles.value, textColorStyles.value, {
8359
+ '--v-border-opacity': props.opacity
8360
+ }, props.style],
8361
+ "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
8362
+ "role": `${attrs.role || 'separator'}`
8363
+ }, null);
8364
+ if (!slots.default) return divider;
8365
+ return vue.createVNode("div", {
8366
+ "class": ['v-divider__wrapper', {
8367
+ 'v-divider__wrapper--vertical': props.vertical,
8368
+ 'v-divider__wrapper--inset': props.inset
8369
+ }]
8370
+ }, [divider, vue.createVNode("div", {
8371
+ "class": "v-divider__content"
8372
+ }, [slots.default()]), divider]);
8373
+ });
8374
+ return {};
8375
+ }
8376
+ });
8377
+
8212
8378
  // Utilities
8213
8379
 
8214
8380
  // List
@@ -9360,68 +9526,6 @@
9360
9526
  }
9361
9527
  });
9362
9528
 
9363
- const makeVDividerProps = propsFactory({
9364
- color: String,
9365
- inset: Boolean,
9366
- length: [Number, String],
9367
- opacity: [Number, String],
9368
- thickness: [Number, String],
9369
- vertical: Boolean,
9370
- ...makeComponentProps(),
9371
- ...makeThemeProps()
9372
- }, 'VDivider');
9373
- const VDivider = genericComponent()({
9374
- name: 'VDivider',
9375
- props: makeVDividerProps(),
9376
- setup(props, _ref) {
9377
- let {
9378
- attrs,
9379
- slots
9380
- } = _ref;
9381
- const {
9382
- themeClasses
9383
- } = provideTheme(props);
9384
- const {
9385
- textColorClasses,
9386
- textColorStyles
9387
- } = useTextColor(() => props.color);
9388
- const dividerStyles = vue.computed(() => {
9389
- const styles = {};
9390
- if (props.length) {
9391
- styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
9392
- }
9393
- if (props.thickness) {
9394
- styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
9395
- }
9396
- return styles;
9397
- });
9398
- useRender(() => {
9399
- const divider = vue.createVNode("hr", {
9400
- "class": [{
9401
- 'v-divider': true,
9402
- 'v-divider--inset': props.inset,
9403
- 'v-divider--vertical': props.vertical
9404
- }, themeClasses.value, textColorClasses.value, props.class],
9405
- "style": [dividerStyles.value, textColorStyles.value, {
9406
- '--v-border-opacity': props.opacity
9407
- }, props.style],
9408
- "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
9409
- "role": `${attrs.role || 'separator'}`
9410
- }, null);
9411
- if (!slots.default) return divider;
9412
- return vue.createVNode("div", {
9413
- "class": ['v-divider__wrapper', {
9414
- 'v-divider__wrapper--vertical': props.vertical,
9415
- 'v-divider__wrapper--inset': props.inset
9416
- }]
9417
- }, [divider, vue.createVNode("div", {
9418
- "class": "v-divider__content"
9419
- }, [slots.default()]), divider]);
9420
- });
9421
- return {};
9422
- }
9423
- });
9424
-
9425
9529
  // Types
9426
9530
 
9427
9531
  const makeVListChildrenProps = propsFactory({
@@ -12339,7 +12443,12 @@
12339
12443
  }
12340
12444
  function calculateOffset(index) {
12341
12445
  index = clamp(index, 0, items.value.length - 1);
12342
- return offsets[index] || 0;
12446
+ const whole = Math.floor(index);
12447
+ const fraction = index % 1;
12448
+ const next = whole + 1;
12449
+ const wholeOffset = offsets[whole] || 0;
12450
+ const nextOffset = offsets[next] || wholeOffset;
12451
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12343
12452
  }
12344
12453
  function calculateIndex(scrollTop) {
12345
12454
  return binaryClosest(offsets, scrollTop);
@@ -12970,6 +13079,22 @@
12970
13079
  key: item.value,
12971
13080
  onClick: () => select(item, null)
12972
13081
  });
13082
+ if (item.raw.type === 'divider') {
13083
+ return slots.divider?.({
13084
+ props: item.raw,
13085
+ index
13086
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13087
+ "key": `divider-${index}`
13088
+ }), null);
13089
+ }
13090
+ if (item.raw.type === 'subheader') {
13091
+ return slots.subheader?.({
13092
+ props: item.raw,
13093
+ index
13094
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13095
+ "key": `subheader-${index}`
13096
+ }), null);
13097
+ }
12973
13098
  return slots.item?.({
12974
13099
  item,
12975
13100
  index,
@@ -13130,6 +13255,9 @@
13130
13255
  let match = -1;
13131
13256
  if ((query || customFiltersLength > 0) && !options?.noFilter) {
13132
13257
  if (typeof item === 'object') {
13258
+ if (['divider', 'subheader'].includes(item.raw?.type)) {
13259
+ continue;
13260
+ }
13133
13261
  const filterKeys = keys || Object.keys(transformed);
13134
13262
  for (const key of filterKeys) {
13135
13263
  const value = getPropertyFromItem(transformed, key);
@@ -13568,6 +13696,22 @@
13568
13696
  active: highlightFirst.value && index === 0 ? true : undefined,
13569
13697
  onClick: () => select(item, null)
13570
13698
  });
13699
+ if (item.raw.type === 'divider') {
13700
+ return slots.divider?.({
13701
+ props: item.raw,
13702
+ index
13703
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
13704
+ "key": `divider-${index}`
13705
+ }), null);
13706
+ }
13707
+ if (item.raw.type === 'subheader') {
13708
+ return slots.subheader?.({
13709
+ props: item.raw,
13710
+ index
13711
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
13712
+ "key": `subheader-${index}`
13713
+ }), null);
13714
+ }
13571
13715
  return slots.item?.({
13572
13716
  item,
13573
13717
  index,
@@ -17978,6 +18122,7 @@
17978
18122
  _search.value = val ?? '';
17979
18123
  if (!props.multiple && !hasSelectionSlot.value) {
17980
18124
  model.value = [transformItem$3(props, val)];
18125
+ vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
17981
18126
  }
17982
18127
  if (val && props.multiple && props.delimiters?.length) {
17983
18128
  const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
@@ -18294,6 +18439,22 @@
18294
18439
  active: highlightFirst.value && index === 0 ? true : undefined,
18295
18440
  onClick: () => select(item, null)
18296
18441
  });
18442
+ if (item.raw.type === 'divider') {
18443
+ return slots.divider?.({
18444
+ props: item.raw,
18445
+ index
18446
+ }) ?? vue.createVNode(VDivider, vue.mergeProps(item.props, {
18447
+ "key": `divider-${index}`
18448
+ }), null);
18449
+ }
18450
+ if (item.raw.type === 'subheader') {
18451
+ return slots.subheader?.({
18452
+ props: item.raw,
18453
+ index
18454
+ }) ?? vue.createVNode(VListSubheader, vue.mergeProps(item.props, {
18455
+ "key": `subheader-${index}`
18456
+ }), null);
18457
+ }
18297
18458
  return slots.item?.({
18298
18459
  item,
18299
18460
  index,
@@ -24717,6 +24878,10 @@
24717
24878
  type: Number,
24718
24879
  default: 0
24719
24880
  },
24881
+ minFractionDigits: {
24882
+ type: Number,
24883
+ default: null
24884
+ },
24720
24885
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
24721
24886
  }, 'VNumberInput');
24722
24887
  const VNumberInput = genericComponent()({
@@ -24747,9 +24912,19 @@
24747
24912
  } = useFocus(props);
24748
24913
  function correctPrecision(val) {
24749
24914
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
24750
- const fixed = precision == null ? String(val) : val.toFixed(precision);
24751
- return isFocused.value ? Number(fixed).toString() // trim zeros
24752
- : fixed;
24915
+ if (precision == null) {
24916
+ return String(val);
24917
+ }
24918
+ let fixed = val.toFixed(precision);
24919
+ if (isFocused.value) {
24920
+ return Number(fixed).toString(); // trim zeros
24921
+ }
24922
+ if ((props.minFractionDigits ?? precision) < precision) {
24923
+ const trimLimit = precision - props.minFractionDigits;
24924
+ const [baseDigits, fractionDigits] = fixed.split('.');
24925
+ fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
24926
+ }
24927
+ return fixed;
24753
24928
  }
24754
24929
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
24755
24930
  const _inputText = vue.shallowRef(null);
@@ -24802,6 +24977,7 @@
24802
24977
  }
24803
24978
  };
24804
24979
  vue.watch(() => props.precision, () => formatInputValue());
24980
+ vue.watch(() => props.minFractionDigits, () => formatInputValue());
24805
24981
  vue.onMounted(() => {
24806
24982
  clampModel();
24807
24983
  });
@@ -24903,7 +25079,7 @@
24903
25079
  inputText.value = null;
24904
25080
  return;
24905
25081
  }
24906
- inputText.value = props.precision == null ? String(model.value) : model.value.toFixed(props.precision);
25082
+ inputText.value = correctPrecision(model.value);
24907
25083
  }
24908
25084
  function trimDecimalZeros() {
24909
25085
  if (controlsDisabled.value) return;
@@ -29870,11 +30046,6 @@
29870
30046
  hideOverlay: Boolean,
29871
30047
  icon: [String, Function, Object],
29872
30048
  iconColor: String,
29873
- iconSize: [Number, String],
29874
- iconSizes: {
29875
- type: Array,
29876
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
29877
- },
29878
30049
  loading: Boolean,
29879
30050
  opacity: [Number, String],
29880
30051
  readonly: Boolean,
@@ -29894,6 +30065,7 @@
29894
30065
  ...makeBorderProps(),
29895
30066
  ...makeComponentProps(),
29896
30067
  ...makeElevationProps(),
30068
+ ...makeIconSizeProps(),
29897
30069
  ...makeRoundedProps(),
29898
30070
  ...makeTagProps({
29899
30071
  tag: 'button'
@@ -29948,7 +30120,6 @@
29948
30120
  })()
29949
30121
  }));
29950
30122
  const btnSizeMap = new Map(props.sizes);
29951
- const iconSizeMap = new Map(props.iconSizes);
29952
30123
  function onClick() {
29953
30124
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
29954
30125
  isActive.value = !isActive.value;
@@ -29960,12 +30131,12 @@
29960
30131
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
29961
30132
  const btnHeight = props.height ?? btnSize;
29962
30133
  const btnWidth = props.width ?? btnSize;
29963
- const _iconSize = props.iconSize;
29964
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
29965
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30134
+ const {
30135
+ iconSize
30136
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
29966
30137
  const iconProps = {
29967
30138
  icon,
29968
- size: iconSize,
30139
+ size: iconSize.value,
29969
30140
  iconColor: props.iconColor,
29970
30141
  opacity: props.opacity
29971
30142
  };
@@ -30008,7 +30179,7 @@
30008
30179
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
30009
30180
  "indeterminate": "disable-shrink",
30010
30181
  "width": "2",
30011
- "size": iconSize
30182
+ "size": iconSize.value
30012
30183
  }, null)])]
30013
30184
  });
30014
30185
  });
@@ -31918,7 +32089,7 @@
31918
32089
  };
31919
32090
  });
31920
32091
  }
31921
- const version$1 = "3.8.5-master.2025-05-20";
32092
+ const version$1 = "3.8.6-dev.2025-05-21";
31922
32093
  createVuetify$1.version = version$1;
31923
32094
 
31924
32095
  // Vue's inject() can only be used in setup
@@ -32216,7 +32387,7 @@
32216
32387
 
32217
32388
  /* eslint-disable local-rules/sort-imports */
32218
32389
 
32219
- const version = "3.8.5-master.2025-05-20";
32390
+ const version = "3.8.6-dev.2025-05-21";
32220
32391
 
32221
32392
  /* eslint-disable local-rules/sort-imports */
32222
32393