@vuetify/nightly 3.8.4-master.2025-05-12 → 3.8.5-dev.2025-05-14

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 (101) hide show
  1. package/CHANGELOG.md +20 -12
  2. package/dist/_component-variables-labs.sass +1 -0
  3. package/dist/json/attributes.json +2152 -1792
  4. package/dist/json/importMap-labs.json +40 -36
  5. package/dist/json/importMap.json +106 -106
  6. package/dist/json/tags.json +95 -0
  7. package/dist/json/web-types.json +5016 -3760
  8. package/dist/vuetify-labs.cjs +429 -61
  9. package/dist/vuetify-labs.css +4205 -4149
  10. package/dist/vuetify-labs.d.ts +2274 -1142
  11. package/dist/vuetify-labs.esm.js +430 -62
  12. package/dist/vuetify-labs.esm.js.map +1 -1
  13. package/dist/vuetify-labs.js +429 -61
  14. package/dist/vuetify-labs.min.css +2 -2
  15. package/dist/vuetify.cjs +151 -41
  16. package/dist/vuetify.cjs.map +1 -1
  17. package/dist/vuetify.css +4725 -4672
  18. package/dist/vuetify.d.ts +544 -487
  19. package/dist/vuetify.esm.js +152 -42
  20. package/dist/vuetify.esm.js.map +1 -1
  21. package/dist/vuetify.js +151 -41
  22. package/dist/vuetify.js.map +1 -1
  23. package/dist/vuetify.min.css +2 -2
  24. package/dist/vuetify.min.js +1181 -1173
  25. package/dist/vuetify.min.js.map +1 -1
  26. package/lib/components/VAlert/VAlert.css +6 -1
  27. package/lib/components/VAlert/VAlert.d.ts +35 -0
  28. package/lib/components/VAlert/VAlert.js +14 -9
  29. package/lib/components/VAlert/VAlert.js.map +1 -1
  30. package/lib/components/VAlert/VAlert.sass +7 -1
  31. package/lib/components/VAutocomplete/VAutocomplete.d.ts +94 -94
  32. package/lib/components/VBottomSheet/VBottomSheet.css +1 -1
  33. package/lib/components/VBottomSheet/VBottomSheet.sass +1 -1
  34. package/lib/components/VBtn/VBtn.css +25 -0
  35. package/lib/components/VBtn/VBtn.sass +9 -0
  36. package/lib/components/VBtn/_variables.scss +1 -0
  37. package/lib/components/VBtnGroup/VBtnGroup.css +30 -7
  38. package/lib/components/VBtnGroup/VBtnGroup.d.ts +58 -32
  39. package/lib/components/VBtnGroup/VBtnGroup.js +7 -3
  40. package/lib/components/VBtnGroup/VBtnGroup.js.map +1 -1
  41. package/lib/components/VBtnGroup/VBtnGroup.sass +44 -17
  42. package/lib/components/VBtnToggle/VBtnToggle.d.ts +25 -0
  43. package/lib/components/VCheckbox/VCheckbox.d.ts +3 -3
  44. package/lib/components/VCombobox/VCombobox.d.ts +94 -94
  45. package/lib/components/VField/VField.d.ts +3 -3
  46. package/lib/components/VFileInput/VFileInput.d.ts +15 -15
  47. package/lib/components/VInput/VInput.d.ts +4 -4
  48. package/lib/components/VNumberInput/VNumberInput.d.ts +89 -89
  49. package/lib/components/VOverlay/VOverlay.css +1 -1
  50. package/lib/components/VOverlay/_variables.scss +1 -1
  51. package/lib/components/VRadioGroup/VRadioGroup.d.ts +3 -3
  52. package/lib/components/VRangeSlider/VRangeSlider.d.ts +3 -3
  53. package/lib/components/VSelect/VSelect.d.ts +94 -94
  54. package/lib/components/VSlider/VSlider.d.ts +3 -3
  55. package/lib/components/VSnackbarQueue/VSnackbarQueue.d.ts +3 -1
  56. package/lib/components/VSnackbarQueue/VSnackbarQueue.js.map +1 -1
  57. package/lib/components/VSwitch/VSwitch.d.ts +3 -3
  58. package/lib/components/VTextField/VTextField.d.ts +27 -27
  59. package/lib/components/VTextarea/VTextarea.d.ts +15 -15
  60. package/lib/composables/calendar.d.ts +1 -0
  61. package/lib/composables/calendar.js.map +1 -1
  62. package/lib/composables/dateFormat.d.ts +24 -0
  63. package/lib/composables/dateFormat.js +112 -0
  64. package/lib/composables/dateFormat.js.map +1 -0
  65. package/lib/composables/iconSizes.d.ts +28 -0
  66. package/lib/composables/iconSizes.js +23 -0
  67. package/lib/composables/iconSizes.js.map +1 -0
  68. package/lib/composables/theme.d.ts +6 -1
  69. package/lib/composables/theme.js +94 -26
  70. package/lib/composables/theme.js.map +1 -1
  71. package/lib/composables/virtual.js +6 -1
  72. package/lib/composables/virtual.js.map +1 -1
  73. package/lib/entry-bundler.js +1 -1
  74. package/lib/entry-bundler.js.map +1 -1
  75. package/lib/framework.d.ts +51 -43
  76. package/lib/framework.js +1 -1
  77. package/lib/framework.js.map +1 -1
  78. package/lib/iconsets/mdi.js +2 -1
  79. package/lib/iconsets/mdi.js.map +1 -1
  80. package/lib/labs/VColorInput/VColorInput.css +4 -0
  81. package/lib/labs/VColorInput/VColorInput.d.ts +1767 -0
  82. package/lib/labs/VColorInput/VColorInput.js +129 -0
  83. package/lib/labs/VColorInput/VColorInput.js.map +1 -0
  84. package/lib/labs/VColorInput/VColorInput.sass +7 -0
  85. package/lib/labs/VColorInput/_variables.scss +2 -0
  86. package/lib/labs/VColorInput/index.d.ts +1 -0
  87. package/lib/labs/VColorInput/index.js +2 -0
  88. package/lib/labs/VColorInput/index.js.map +1 -0
  89. package/lib/labs/VDateInput/VDateInput.d.ts +133 -108
  90. package/lib/labs/VDateInput/VDateInput.js +43 -10
  91. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  92. package/lib/labs/VIconBtn/VIconBtn.d.ts +29 -29
  93. package/lib/labs/VIconBtn/VIconBtn.js +7 -11
  94. package/lib/labs/VIconBtn/VIconBtn.js.map +1 -1
  95. package/lib/labs/components.d.ts +1 -0
  96. package/lib/labs/components.js +1 -0
  97. package/lib/labs/components.js.map +1 -1
  98. package/lib/util/globals.d.ts +1 -0
  99. package/lib/util/globals.js +1 -0
  100. package/lib/util/globals.js.map +1 -1
  101. package/package.json +2 -1
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * Vuetify v3.8.4-master.2025-05-12
2
+ * Vuetify v3.8.5-dev.2025-05-14
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
- import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, camelize, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, createVNode, TransitionGroup, Transition, mergeProps, toRefs, toValue, isRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
7
+ import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, camelize, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, createVNode, TransitionGroup, Transition, mergeProps, toRefs, toValue, isRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
8
8
 
9
9
  // Types
10
10
  // eslint-disable-line vue/prefer-import-from-vue
@@ -81,6 +81,7 @@ const IN_BROWSER = typeof window !== 'undefined';
81
81
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
82
82
  const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
83
83
  const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
84
+ const SUPPORTS_MATCH_MEDIA = IN_BROWSER && 'matchMedia' in window && typeof window.matchMedia === 'function';
84
85
 
85
86
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
86
87
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -2295,6 +2296,7 @@ const makeThemeProps = propsFactory({
2295
2296
  function genDefaults$2() {
2296
2297
  return {
2297
2298
  defaultTheme: 'light',
2299
+ prefix: 'v-',
2298
2300
  variations: {
2299
2301
  colors: [],
2300
2302
  lighten: 0,
@@ -2376,7 +2378,10 @@ function genDefaults$2() {
2376
2378
  }
2377
2379
  }
2378
2380
  },
2379
- stylesheetId: 'vuetify-theme-stylesheet'
2381
+ stylesheetId: 'vuetify-theme-stylesheet',
2382
+ scoped: false,
2383
+ unimportant: false,
2384
+ utilities: true
2380
2385
  };
2381
2386
  }
2382
2387
  function parseThemeOptions() {
@@ -2399,21 +2404,21 @@ function parseThemeOptions() {
2399
2404
  function createCssClass(lines, selector, content, scope) {
2400
2405
  lines.push(`${getScopedSelector(selector, scope)} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
2401
2406
  }
2402
- function genCssVariables(theme) {
2407
+ function genCssVariables(theme, prefix) {
2403
2408
  const lightOverlay = theme.dark ? 2 : 1;
2404
2409
  const darkOverlay = theme.dark ? 1 : 2;
2405
2410
  const variables = [];
2406
2411
  for (const [key, value] of Object.entries(theme.colors)) {
2407
2412
  const rgb = parseColor(value);
2408
- variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2413
+ variables.push(`--${prefix}theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
2409
2414
  if (!key.startsWith('on-')) {
2410
- variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2415
+ variables.push(`--${prefix}theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
2411
2416
  }
2412
2417
  }
2413
2418
  for (const [key, value] of Object.entries(theme.variables)) {
2414
2419
  const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
2415
2420
  const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
2416
- variables.push(`--v-${key}: ${rgb ?? value}`);
2421
+ variables.push(`--${prefix}${key}: ${rgb ?? value}`);
2417
2422
  }
2418
2423
  return variables;
2419
2424
  }
@@ -2457,7 +2462,8 @@ function getScopedSelector(selector, scope) {
2457
2462
  const scopeSelector = `:where(${scope})`;
2458
2463
  return selector === ':root' ? scopeSelector : `${scopeSelector} ${selector}`;
2459
2464
  }
2460
- function upsertStyles(styleEl, styles) {
2465
+ function upsertStyles(id, cspNonce, styles) {
2466
+ const styleEl = getOrCreateStyleElement(id, cspNonce);
2461
2467
  if (!styleEl) return;
2462
2468
  styleEl.innerHTML = styles;
2463
2469
  }
@@ -2477,8 +2483,17 @@ function getOrCreateStyleElement(id, cspNonce) {
2477
2483
  // Composables
2478
2484
  function createTheme(options) {
2479
2485
  const parsedOptions = parseThemeOptions(options);
2480
- const name = shallowRef(parsedOptions.defaultTheme);
2486
+ const _name = shallowRef(parsedOptions.defaultTheme);
2481
2487
  const themes = ref(parsedOptions.themes);
2488
+ const systemName = shallowRef('light');
2489
+ const name = computed({
2490
+ get() {
2491
+ return _name.value === 'system' ? systemName.value : _name.value;
2492
+ },
2493
+ set(val) {
2494
+ _name.value = val;
2495
+ }
2496
+ });
2482
2497
  const computedThemes = computed(() => {
2483
2498
  const acc = {};
2484
2499
  for (const [name, original] of Object.entries(themes.value)) {
@@ -2499,28 +2514,49 @@ function createTheme(options) {
2499
2514
  const current = toRef(() => computedThemes.value[name.value]);
2500
2515
  const styles = computed(() => {
2501
2516
  const lines = [];
2517
+ const important = parsedOptions.unimportant ? '' : ' !important';
2518
+ const scoped = parsedOptions.scoped ? parsedOptions.prefix : '';
2502
2519
  if (current.value?.dark) {
2503
2520
  createCssClass(lines, ':root', ['color-scheme: dark'], parsedOptions.scope);
2504
2521
  }
2505
- createCssClass(lines, ':root', genCssVariables(current.value), parsedOptions.scope);
2522
+ createCssClass(lines, ':root', genCssVariables(current.value, parsedOptions.prefix), parsedOptions.scope);
2506
2523
  for (const [themeName, theme] of Object.entries(computedThemes.value)) {
2507
- createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)], parsedOptions.scope);
2508
- }
2509
- const bgLines = [];
2510
- const fgLines = [];
2511
- const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2512
- for (const key of colors) {
2513
- if (key.startsWith('on-')) {
2514
- createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2515
- } else {
2516
- 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);
2517
- createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`], parsedOptions.scope);
2518
- createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`], parsedOptions.scope);
2524
+ createCssClass(lines, `.${parsedOptions.prefix}theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme, parsedOptions.prefix)], parsedOptions.scope);
2525
+ }
2526
+ if (parsedOptions.utilities) {
2527
+ const bgLines = [];
2528
+ const fgLines = [];
2529
+ const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
2530
+ for (const key of colors) {
2531
+ if (key.startsWith('on-')) {
2532
+ createCssClass(fgLines, `.${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2533
+ } else {
2534
+ 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);
2535
+ createCssClass(fgLines, `.${scoped}text-${key}`, [`color: rgb(var(--${parsedOptions.prefix}theme-${key}))${important}`], parsedOptions.scope);
2536
+ createCssClass(fgLines, `.${scoped}border-${key}`, [`--${parsedOptions.prefix}border-color: var(--${parsedOptions.prefix}theme-${key})`], parsedOptions.scope);
2537
+ }
2519
2538
  }
2539
+ lines.push(...bgLines, ...fgLines);
2520
2540
  }
2521
- lines.push(...bgLines, ...fgLines);
2522
2541
  return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
2523
2542
  });
2543
+ const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`);
2544
+ const themeNames = toRef(() => Object.keys(computedThemes.value));
2545
+ if (SUPPORTS_MATCH_MEDIA) {
2546
+ const media = window.matchMedia('(prefers-color-scheme: dark)');
2547
+ function updateSystemName() {
2548
+ systemName.value = media.matches ? 'dark' : 'light';
2549
+ }
2550
+ updateSystemName();
2551
+ media.addEventListener('change', updateSystemName, {
2552
+ passive: true
2553
+ });
2554
+ if (getCurrentScope()) {
2555
+ onScopeDispose(() => {
2556
+ media.removeEventListener('change', updateSystemName);
2557
+ });
2558
+ }
2559
+ }
2524
2560
  function install(app) {
2525
2561
  if (parsedOptions.isDisabled) return;
2526
2562
  const head = app._context.provides.usehead;
@@ -2558,22 +2594,55 @@ function createTheme(options) {
2558
2594
  updateStyles();
2559
2595
  }
2560
2596
  function updateStyles() {
2561
- upsertStyles(getOrCreateStyleElement(parsedOptions.stylesheetId, parsedOptions.cspNonce), styles.value);
2597
+ upsertStyles(parsedOptions.stylesheetId, parsedOptions.cspNonce, styles.value);
2562
2598
  }
2563
2599
  }
2564
2600
  }
2565
- const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
2601
+ function change(themeName) {
2602
+ if (!themeNames.value.includes(themeName)) {
2603
+ consoleWarn(`Theme "${themeName}" not found on the Vuetify theme instance`);
2604
+ return;
2605
+ }
2606
+ name.value = themeName;
2607
+ }
2608
+ function cycle() {
2609
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : themeNames.value;
2610
+ const currentIndex = themeArray.indexOf(name.value);
2611
+ const nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % themeArray.length;
2612
+ change(themeArray[nextIndex]);
2613
+ }
2614
+ function toggle() {
2615
+ let themeArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['light', 'dark'];
2616
+ cycle(themeArray);
2617
+ }
2618
+ const globalName = new Proxy(name, {
2619
+ get(target, prop) {
2620
+ return target[prop];
2621
+ },
2622
+ set(target, prop, val) {
2623
+ if (prop === 'value') {
2624
+ deprecate(`theme.global.name.value = ${val}`, `theme.change('${val}')`);
2625
+ }
2626
+ // @ts-expect-error
2627
+ target[prop] = val;
2628
+ return true;
2629
+ }
2630
+ });
2566
2631
  return {
2567
2632
  install,
2633
+ change,
2634
+ cycle,
2635
+ toggle,
2568
2636
  isDisabled: parsedOptions.isDisabled,
2569
2637
  name,
2570
2638
  themes,
2571
2639
  current,
2572
2640
  computedThemes,
2641
+ prefix: parsedOptions.prefix,
2573
2642
  themeClasses,
2574
2643
  styles,
2575
2644
  global: {
2576
- name,
2645
+ name: globalName,
2577
2646
  current
2578
2647
  }
2579
2648
  };
@@ -2584,7 +2653,7 @@ function provideTheme(props) {
2584
2653
  if (!theme) throw new Error('Could not find Vuetify theme injection');
2585
2654
  const name = toRef(() => props.theme ?? theme.name.value);
2586
2655
  const current = toRef(() => theme.themes.value[name.value]);
2587
- const themeClasses = toRef(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
2656
+ const themeClasses = toRef(() => theme.isDisabled ? undefined : `${theme.prefix}theme--${name.value}`);
2588
2657
  const newTheme = {
2589
2658
  ...theme,
2590
2659
  name,
@@ -4131,9 +4200,15 @@ function useVariant(props) {
4131
4200
  };
4132
4201
  }
4133
4202
 
4203
+ // Types
4204
+
4134
4205
  const makeVBtnGroupProps = propsFactory({
4135
4206
  baseColor: String,
4136
4207
  divided: Boolean,
4208
+ direction: {
4209
+ type: String,
4210
+ default: 'horizontal'
4211
+ },
4137
4212
  ...makeBorderProps(),
4138
4213
  ...makeComponentProps(),
4139
4214
  ...makeDensityProps(),
@@ -4167,7 +4242,7 @@ const VBtnGroup = genericComponent()({
4167
4242
  } = useRounded(props);
4168
4243
  provideDefaults({
4169
4244
  VBtn: {
4170
- height: 'auto',
4245
+ height: toRef(() => props.direction === 'horizontal' ? 'auto' : null),
4171
4246
  baseColor: toRef(() => props.baseColor),
4172
4247
  color: toRef(() => props.color),
4173
4248
  density: toRef(() => props.density),
@@ -4177,7 +4252,7 @@ const VBtnGroup = genericComponent()({
4177
4252
  });
4178
4253
  useRender(() => {
4179
4254
  return createVNode(props.tag, {
4180
- "class": ['v-btn-group', {
4255
+ "class": ['v-btn-group', `v-btn-group--${props.direction}`, {
4181
4256
  'v-btn-group--divided': props.divided
4182
4257
  }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
4183
4258
  "style": props.style
@@ -4506,7 +4581,8 @@ const aliases = {
4506
4581
  treeviewCollapse: 'mdi-menu-down',
4507
4582
  treeviewExpand: 'mdi-menu-right',
4508
4583
  eyeDropper: 'mdi-eyedropper',
4509
- upload: 'mdi-cloud-upload'
4584
+ upload: 'mdi-cloud-upload',
4585
+ color: 'mdi-palette'
4510
4586
  };
4511
4587
  const mdi = {
4512
4588
  // Not using mergeProps here, functional components merge props by default (?)
@@ -5864,6 +5940,31 @@ const VAppBarTitle = genericComponent()({
5864
5940
  // Utilities
5865
5941
  const VAlertTitle = createSimpleFunctional('v-alert-title');
5866
5942
 
5943
+ // Utilities
5944
+
5945
+ // Types
5946
+
5947
+ // Types
5948
+
5949
+ // Composables
5950
+ const makeIconSizeProps = propsFactory({
5951
+ iconSize: [Number, String],
5952
+ iconSizes: {
5953
+ type: Array,
5954
+ default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
5955
+ }
5956
+ }, 'iconSize');
5957
+ function useIconSizes(props, fallback) {
5958
+ const iconSize = computed(() => {
5959
+ const iconSizeMap = new Map(props.iconSizes);
5960
+ const _iconSize = props.iconSize ?? fallback() ?? 'default';
5961
+ return iconSizeMap.has(_iconSize) ? iconSizeMap.get(_iconSize) : _iconSize;
5962
+ });
5963
+ return {
5964
+ iconSize
5965
+ };
5966
+ }
5967
+
5867
5968
  // Types
5868
5969
 
5869
5970
  const allowedTypes = ['success', 'info', 'warning', 'error'];
@@ -5903,6 +6004,7 @@ const makeVAlertProps = propsFactory({
5903
6004
  ...makeDensityProps(),
5904
6005
  ...makeDimensionProps(),
5905
6006
  ...makeElevationProps(),
6007
+ ...makeIconSizeProps(),
5906
6008
  ...makeLocationProps(),
5907
6009
  ...makePositionProps(),
5908
6010
  ...makeRoundedProps(),
@@ -5930,6 +6032,9 @@ const VAlert = genericComponent()({
5930
6032
  if (!props.type) return props.icon;
5931
6033
  return props.icon ?? `$${props.type}`;
5932
6034
  });
6035
+ const {
6036
+ iconSize
6037
+ } = useIconSizes(props, () => props.prominent ? 44 : 28);
5933
6038
  const {
5934
6039
  themeClasses
5935
6040
  } = provideTheme(props);
@@ -5977,6 +6082,11 @@ const VAlert = genericComponent()({
5977
6082
  const hasPrepend = !!(slots.prepend || icon.value);
5978
6083
  const hasTitle = !!(slots.title || props.title);
5979
6084
  const hasClose = !!(slots.close || props.closable);
6085
+ const iconProps = {
6086
+ density: props.density,
6087
+ icon: icon.value,
6088
+ size: iconSize.value
6089
+ };
5980
6090
  return isActive.value && createVNode(props.tag, {
5981
6091
  "class": ['v-alert', props.border && {
5982
6092
  'v-alert--border': !!props.border,
@@ -5994,19 +6104,14 @@ const VAlert = genericComponent()({
5994
6104
  }, null), hasPrepend && createVNode("div", {
5995
6105
  "key": "prepend",
5996
6106
  "class": "v-alert__prepend"
5997
- }, [!slots.prepend ? createVNode(VIcon, {
5998
- "key": "prepend-icon",
5999
- "density": props.density,
6000
- "icon": icon.value,
6001
- "size": props.prominent ? 44 : 28
6002
- }, null) : createVNode(VDefaultsProvider, {
6107
+ }, [!slots.prepend ? createVNode(VIcon, mergeProps({
6108
+ "key": "prepend-icon"
6109
+ }, iconProps), null) : createVNode(VDefaultsProvider, {
6003
6110
  "key": "prepend-defaults",
6004
6111
  "disabled": !icon.value,
6005
6112
  "defaults": {
6006
6113
  VIcon: {
6007
- density: props.density,
6008
- icon: icon.value,
6009
- size: props.prominent ? 44 : 28
6114
+ ...iconProps
6010
6115
  }
6011
6116
  }
6012
6117
  }, slots.prepend)]), createVNode("div", {
@@ -12352,7 +12457,12 @@ function useVirtual(props, items) {
12352
12457
  }
12353
12458
  function calculateOffset(index) {
12354
12459
  index = clamp(index, 0, items.value.length - 1);
12355
- return offsets[index] || 0;
12460
+ const whole = Math.floor(index);
12461
+ const fraction = index % 1;
12462
+ const next = whole + 1;
12463
+ const wholeOffset = offsets[whole] || 0;
12464
+ const nextOffset = offsets[next] || wholeOffset;
12465
+ return wholeOffset + (nextOffset - wholeOffset) * fraction;
12356
12466
  }
12357
12467
  function calculateIndex(scrollTop) {
12358
12468
  return binaryClosest(offsets, scrollTop);
@@ -29072,6 +29182,236 @@ const VCalendar = genericComponent()({
29072
29182
 
29073
29183
  // Types
29074
29184
 
29185
+ const makeVColorInputProps = propsFactory({
29186
+ pip: Boolean,
29187
+ pipIcon: {
29188
+ type: String,
29189
+ default: '$color'
29190
+ },
29191
+ ...makeFocusProps(),
29192
+ ...makeVConfirmEditProps(),
29193
+ ...makeVTextFieldProps(),
29194
+ ...omit(makeVColorPickerProps(), ['width'])
29195
+ }, 'VColorInput');
29196
+ const VColorInput = genericComponent()({
29197
+ name: 'VColorInput',
29198
+ props: makeVColorInputProps(),
29199
+ emits: {
29200
+ 'update:modelValue': val => true
29201
+ },
29202
+ setup(props, _ref) {
29203
+ let {
29204
+ slots
29205
+ } = _ref;
29206
+ const {
29207
+ isFocused,
29208
+ focus,
29209
+ blur
29210
+ } = useFocus(props);
29211
+ const model = useProxiedModel(props, 'modelValue');
29212
+ const menu = shallowRef(false);
29213
+ const isInteractive = computed(() => !props.disabled && !props.readonly);
29214
+ const display = computed(() => model.value || null);
29215
+ function onKeydown(e) {
29216
+ if (e.key !== 'Enter') return;
29217
+ if (!menu.value || !isFocused.value) {
29218
+ menu.value = true;
29219
+ return;
29220
+ }
29221
+ const target = e.target;
29222
+ model.value = target.value;
29223
+ }
29224
+ function onClick(e) {
29225
+ e.preventDefault();
29226
+ e.stopPropagation();
29227
+ menu.value = true;
29228
+ }
29229
+ function onSave() {
29230
+ menu.value = false;
29231
+ }
29232
+ useRender(() => {
29233
+ const confirmEditProps = VConfirmEdit.filterProps(props);
29234
+ const colorPickerProps = VColorPicker.filterProps(omit(props, ['active', 'color']));
29235
+ const textFieldProps = VTextField.filterProps(omit(props, ['prependInnerIcon']));
29236
+ const hasPrepend = !!(slots.prepend || props.pipIcon);
29237
+ return createVNode(VTextField, mergeProps(textFieldProps, {
29238
+ "class": ['v-color-input', props.class],
29239
+ "style": props.style,
29240
+ "modelValue": display.value,
29241
+ "onKeydown": isInteractive.value ? onKeydown : undefined,
29242
+ "focused": menu.value || isFocused.value,
29243
+ "onFocus": focus,
29244
+ "onBlur": blur,
29245
+ "onClick:control": isInteractive.value ? onClick : undefined,
29246
+ "onClick:prependInner": isInteractive.value ? onClick : undefined,
29247
+ "onClick:appendInner": isInteractive.value ? onClick : undefined,
29248
+ "onUpdate:modelValue": val => {
29249
+ model.value = val;
29250
+ }
29251
+ }), {
29252
+ ...slots,
29253
+ prepend: props.pipIcon ? arg => createVNode(Fragment, null, [hasPrepend && createVNode(VIcon, {
29254
+ "color": props.pip ? model.value : undefined,
29255
+ "icon": props.pipIcon
29256
+ }, null), slots.prepend?.(arg)]) : undefined,
29257
+ default: () => createVNode(Fragment, null, [createVNode(VMenu, {
29258
+ "modelValue": menu.value,
29259
+ "onUpdate:modelValue": $event => menu.value = $event,
29260
+ "activator": "parent",
29261
+ "min-width": "0",
29262
+ "closeOnContentClick": false,
29263
+ "openOnClick": false
29264
+ }, {
29265
+ default: () => [createVNode(VConfirmEdit, mergeProps(confirmEditProps, {
29266
+ "modelValue": model.value,
29267
+ "onUpdate:modelValue": $event => model.value = $event,
29268
+ "onSave": onSave
29269
+ }), {
29270
+ default: _ref2 => {
29271
+ let {
29272
+ actions,
29273
+ model: proxyModel,
29274
+ save,
29275
+ cancel,
29276
+ isPristine
29277
+ } = _ref2;
29278
+ return createVNode(VColorPicker, mergeProps(colorPickerProps, {
29279
+ "modelValue": proxyModel.value,
29280
+ "onUpdate:modelValue": val => {
29281
+ proxyModel.value = val;
29282
+ model.value = val;
29283
+ },
29284
+ "onMousedown": e => e.preventDefault()
29285
+ }), {
29286
+ actions: !props.hideActions ? () => slots.actions?.({
29287
+ save,
29288
+ cancel,
29289
+ isPristine
29290
+ }) ?? actions() : undefined
29291
+ });
29292
+ }
29293
+ })]
29294
+ }), slots.default?.()])
29295
+ });
29296
+ });
29297
+ }
29298
+ });
29299
+
29300
+ // Composables
29301
+
29302
+ // Types
29303
+
29304
+ // Types
29305
+
29306
+ class DateFormatSpec {
29307
+ constructor(order,
29308
+ // mdy | dmy | ymd
29309
+ separator // / | - | .
29310
+ ) {
29311
+ this.order = order;
29312
+ this.separator = separator;
29313
+ }
29314
+ get format() {
29315
+ return this.order.split('').map(sign => `${sign}${sign}`).join(this.separator).replace('yy', 'yyyy');
29316
+ }
29317
+ static canBeParsed(v) {
29318
+ if (typeof v !== 'string') return false;
29319
+ const lowercase = v.toLowerCase();
29320
+ return ['y', 'm', 'd'].every(sign => lowercase.includes(sign)) && ['/', '-', '.'].some(sign => v.includes(sign));
29321
+ }
29322
+ static parse(v) {
29323
+ if (!DateFormatSpec.canBeParsed(v)) {
29324
+ throw new Error(`[${v}] cannot be parsed into date format specification`);
29325
+ }
29326
+ const order = v.toLowerCase().split('').filter((c, i, all) => 'dmy'.includes(c) && all.indexOf(c) === i).join('');
29327
+ const separator = ['/', '-', '.'].find(sign => v.includes(sign));
29328
+ return new DateFormatSpec(order, separator);
29329
+ }
29330
+ }
29331
+ const makeDateFormatProps = propsFactory({
29332
+ inputFormat: {
29333
+ type: String,
29334
+ validator: v => !v || DateFormatSpec.canBeParsed(v)
29335
+ }
29336
+ }, 'date-format');
29337
+ function useDateFormat(props, locale) {
29338
+ const adapter = useDate();
29339
+ function inferFromLocale() {
29340
+ const localeForDateFormat = locale.value ?? 'en-US';
29341
+ const formatFromLocale = Intl.DateTimeFormat(localeForDateFormat, {
29342
+ year: 'numeric',
29343
+ month: '2-digit',
29344
+ day: '2-digit'
29345
+ }).format(adapter.toJsDate(adapter.parseISO('1999-12-07'))).replace(/(07)|(٠٧)|(٢٩)|(۱۶)|(০৭)/, 'dd').replace(/(12)|(١٢)|(٠٨)|(۰۹)|(১২)/, 'mm').replace(/(1999)|(2542)|(١٩٩٩)|(١٤٢٠)|(۱۳۷۸)|(১৯৯৯)/, 'yyyy').replace(/[^ymd\-/.]/g, '').replace(/\.$/, '');
29346
+ if (!DateFormatSpec.canBeParsed(formatFromLocale)) {
29347
+ consoleWarn(`Date format inferred from locale [${localeForDateFormat}] is invalid: [${formatFromLocale}]`);
29348
+ return 'mm/dd/yyyy';
29349
+ }
29350
+ return formatFromLocale;
29351
+ }
29352
+ const currentFormat = toRef(() => {
29353
+ return DateFormatSpec.canBeParsed(props.inputFormat) ? DateFormatSpec.parse(props.inputFormat) : DateFormatSpec.parse(inferFromLocale());
29354
+ });
29355
+ function parseDate(dateString) {
29356
+ function parseDateParts(text) {
29357
+ const parts = text.trim().split(currentFormat.value.separator);
29358
+ return {
29359
+ y: Number(parts[currentFormat.value.order.indexOf('y')]),
29360
+ m: Number(parts[currentFormat.value.order.indexOf('m')]),
29361
+ d: Number(parts[currentFormat.value.order.indexOf('d')])
29362
+ };
29363
+ }
29364
+ function validateDateParts(dateParts) {
29365
+ const {
29366
+ y: year,
29367
+ m: month,
29368
+ d: day
29369
+ } = dateParts;
29370
+ if (!year || !month || !day) return null;
29371
+ if (month < 1 || month > 12) return null;
29372
+ if (day < 1 || day > 31) return null;
29373
+ return {
29374
+ year: autoFixYear(year),
29375
+ month,
29376
+ day
29377
+ };
29378
+ }
29379
+ function autoFixYear(year) {
29380
+ const currentYear = adapter.getYear(adapter.date());
29381
+ if (year > 100 || currentYear % 100 >= 50) {
29382
+ return year;
29383
+ }
29384
+ const currentCentury = ~~(currentYear / 100) * 100;
29385
+ return year < 50 ? currentCentury + year : currentCentury - 100 + year;
29386
+ }
29387
+ const dateParts = parseDateParts(dateString);
29388
+ const validatedParts = validateDateParts(dateParts);
29389
+ if (!validatedParts) return null;
29390
+ const {
29391
+ year,
29392
+ month,
29393
+ day
29394
+ } = validatedParts;
29395
+ const pad = v => String(v).padStart(2, '0');
29396
+ return adapter.parseISO(`${year}-${pad(month)}-${pad(day)}`);
29397
+ }
29398
+ function isValid(text) {
29399
+ return !!parseDate(text);
29400
+ }
29401
+ function formatDate(value) {
29402
+ const parts = adapter.toISO(value).split('-');
29403
+ return currentFormat.value.order.split('').map(sign => parts['ymd'.indexOf(sign)]).join(currentFormat.value.separator);
29404
+ }
29405
+ return {
29406
+ isValid,
29407
+ parseDate,
29408
+ formatDate,
29409
+ parserFormat: toRef(() => currentFormat.value.format)
29410
+ };
29411
+ }
29412
+
29413
+ // Types
29414
+
29075
29415
  // Types
29076
29416
 
29077
29417
  const makeVDateInputProps = propsFactory({
@@ -29080,10 +29420,12 @@ const makeVDateInputProps = propsFactory({
29080
29420
  type: String,
29081
29421
  default: 'bottom start'
29082
29422
  },
29423
+ menu: Boolean,
29083
29424
  updateOn: {
29084
29425
  type: Array,
29085
29426
  default: () => ['blur', 'enter']
29086
29427
  },
29428
+ ...makeDateFormatProps(),
29087
29429
  ...makeDisplayProps({
29088
29430
  mobile: null
29089
29431
  }),
@@ -29092,7 +29434,6 @@ const makeVDateInputProps = propsFactory({
29092
29434
  hideActions: true
29093
29435
  }),
29094
29436
  ...makeVTextFieldProps({
29095
- placeholder: 'mm/dd/yyyy',
29096
29437
  prependIcon: '$calendar'
29097
29438
  }),
29098
29439
  ...omit(makeVDatePickerProps({
@@ -29106,7 +29447,8 @@ const VDateInput = genericComponent()({
29106
29447
  emits: {
29107
29448
  save: value => true,
29108
29449
  cancel: () => true,
29109
- 'update:modelValue': val => true
29450
+ 'update:modelValue': val => true,
29451
+ 'update:menu': val => true
29110
29452
  },
29111
29453
  setup(props, _ref) {
29112
29454
  let {
@@ -29114,9 +29456,16 @@ const VDateInput = genericComponent()({
29114
29456
  slots
29115
29457
  } = _ref;
29116
29458
  const {
29117
- t
29459
+ t,
29460
+ current: currentLocale
29118
29461
  } = useLocale();
29119
29462
  const adapter = useDate();
29463
+ const {
29464
+ isValid,
29465
+ parseDate,
29466
+ formatDate,
29467
+ parserFormat
29468
+ } = useDateFormat(props, currentLocale);
29120
29469
  const {
29121
29470
  mobile
29122
29471
  } = useDisplay(props);
@@ -29127,7 +29476,7 @@ const VDateInput = genericComponent()({
29127
29476
  } = useFocus(props);
29128
29477
  const emptyModelValue = () => props.multiple ? [] : null;
29129
29478
  const model = useProxiedModel(props, 'modelValue', emptyModelValue(), val => Array.isArray(val) ? val.map(item => adapter.toJsDate(item)) : val ? adapter.toJsDate(val) : val, val => Array.isArray(val) ? val.map(item => adapter.date(item)) : val ? adapter.date(val) : val);
29130
- const menu = shallowRef(false);
29479
+ const menu = useProxiedModel(props, 'menu');
29131
29480
  const isEditingInput = shallowRef(false);
29132
29481
  const vTextFieldRef = ref();
29133
29482
  const disabledActions = ref(['save']);
@@ -29135,7 +29484,10 @@ const VDateInput = genericComponent()({
29135
29484
  if (typeof props.displayFormat === 'function') {
29136
29485
  return props.displayFormat(date);
29137
29486
  }
29138
- return adapter.format(date, props.displayFormat ?? 'keyboardDate');
29487
+ if (props.displayFormat) {
29488
+ return adapter.format(date, props.displayFormat ?? 'keyboardDate');
29489
+ }
29490
+ return formatDate(date);
29139
29491
  }
29140
29492
  const display = computed(() => {
29141
29493
  const value = wrapInArray(model.value);
@@ -29170,7 +29522,6 @@ const VDateInput = genericComponent()({
29170
29522
  if (e.key !== 'Enter') return;
29171
29523
  if (!menu.value || !isFocused.value) {
29172
29524
  menu.value = true;
29173
- return;
29174
29525
  }
29175
29526
  if (props.updateOn.includes('enter')) {
29176
29527
  onUserInput(e.target);
@@ -29214,13 +29565,32 @@ const VDateInput = genericComponent()({
29214
29565
  let {
29215
29566
  value
29216
29567
  } = _ref2;
29217
- if (value && !adapter.isValid(value)) return;
29218
- model.value = !value ? emptyModelValue() : value;
29568
+ if (!value.trim()) {
29569
+ model.value = emptyModelValue();
29570
+ } else if (!props.multiple) {
29571
+ if (isValid(value)) {
29572
+ model.value = parseDate(value);
29573
+ }
29574
+ } else {
29575
+ const parts = value.trim().split(/\D+-\D+|[^\d\-/.]+/);
29576
+ if (parts.every(isValid)) {
29577
+ if (props.multiple === 'range') {
29578
+ model.value = getRange(parts);
29579
+ } else {
29580
+ model.value = parts.map(parseDate);
29581
+ }
29582
+ }
29583
+ }
29584
+ }
29585
+ function getRange(inputDates) {
29586
+ const [start, stop] = inputDates.map(parseDate).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
29587
+ const diff = adapter.getDiff(stop ?? start, start, 'days');
29588
+ return [start, ...createRange(diff, 1).map(i => adapter.addDays(start, i))];
29219
29589
  }
29220
29590
  useRender(() => {
29221
29591
  const confirmEditProps = VConfirmEdit.filterProps(props);
29222
29592
  const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'location', 'rounded']));
29223
- const textFieldProps = VTextField.filterProps(props);
29593
+ const textFieldProps = VTextField.filterProps(omit(props, ['placeholder']));
29224
29594
  return createVNode(VTextField, mergeProps({
29225
29595
  "ref": vTextFieldRef
29226
29596
  }, textFieldProps, {
@@ -29228,11 +29598,13 @@ const VDateInput = genericComponent()({
29228
29598
  "style": props.style,
29229
29599
  "modelValue": display.value,
29230
29600
  "inputmode": inputmode.value,
29601
+ "placeholder": props.placeholder ?? parserFormat.value,
29231
29602
  "readonly": isReadonly.value,
29232
29603
  "onKeydown": isInteractive.value ? onKeydown : undefined,
29233
29604
  "focused": menu.value || isFocused.value,
29234
29605
  "onFocus": focus,
29235
29606
  "onBlur": onBlur,
29607
+ "validationValue": model.value,
29236
29608
  "onClick:control": isInteractive.value ? onClick : undefined,
29237
29609
  "onClick:prepend": isInteractive.value ? onClick : undefined,
29238
29610
  "onUpdate:modelValue": onUpdateDisplayModel
@@ -29618,11 +29990,6 @@ const makeVIconBtnProps = propsFactory({
29618
29990
  hideOverlay: Boolean,
29619
29991
  icon: [String, Function, Object],
29620
29992
  iconColor: String,
29621
- iconSize: [Number, String],
29622
- iconSizes: {
29623
- type: Array,
29624
- default: () => [['x-small', 10], ['small', 16], ['default', 24], ['large', 28], ['x-large', 32]]
29625
- },
29626
29993
  loading: Boolean,
29627
29994
  opacity: [Number, String],
29628
29995
  readonly: Boolean,
@@ -29642,6 +30009,7 @@ const makeVIconBtnProps = propsFactory({
29642
30009
  ...makeBorderProps(),
29643
30010
  ...makeComponentProps(),
29644
30011
  ...makeElevationProps(),
30012
+ ...makeIconSizeProps(),
29645
30013
  ...makeRoundedProps(),
29646
30014
  ...makeTagProps({
29647
30015
  tag: 'button'
@@ -29696,7 +30064,6 @@ const VIconBtn = genericComponent()({
29696
30064
  })()
29697
30065
  }));
29698
30066
  const btnSizeMap = new Map(props.sizes);
29699
- const iconSizeMap = new Map(props.iconSizes);
29700
30067
  function onClick() {
29701
30068
  if (props.disabled || props.readonly || isActive.value === undefined || props.tag === 'a' && attrs.href) return;
29702
30069
  isActive.value = !isActive.value;
@@ -29708,12 +30075,12 @@ const VIconBtn = genericComponent()({
29708
30075
  const btnSize = hasNamedSize ? btnSizeMap.get(_btnSize) : _btnSize;
29709
30076
  const btnHeight = props.height ?? btnSize;
29710
30077
  const btnWidth = props.width ?? btnSize;
29711
- const _iconSize = props.iconSize;
29712
- const hasNamedIconSize = iconSizeMap.has(_iconSize);
29713
- const iconSize = !_iconSize ? hasNamedSize ? iconSizeMap.get(_btnSize) : iconSizeMap.get('default') : hasNamedIconSize ? iconSizeMap.get(_iconSize) : _iconSize;
30078
+ const {
30079
+ iconSize
30080
+ } = useIconSizes(props, () => new Map(props.iconSizes).get(_btnSize));
29714
30081
  const iconProps = {
29715
30082
  icon,
29716
- size: iconSize,
30083
+ size: iconSize.value,
29717
30084
  iconColor: props.iconColor,
29718
30085
  opacity: props.opacity
29719
30086
  };
@@ -29756,7 +30123,7 @@ const VIconBtn = genericComponent()({
29756
30123
  "color": typeof props.loading === 'boolean' ? undefined : props.loading,
29757
30124
  "indeterminate": "disable-shrink",
29758
30125
  "width": "2",
29759
- "size": iconSize
30126
+ "size": iconSize.value
29760
30127
  }, null)])]
29761
30128
  });
29762
30129
  });
@@ -31199,6 +31566,7 @@ var components = /*#__PURE__*/Object.freeze({
31199
31566
  VClassIcon: VClassIcon,
31200
31567
  VCode: VCode,
31201
31568
  VCol: VCol,
31569
+ VColorInput: VColorInput,
31202
31570
  VColorPicker: VColorPicker,
31203
31571
  VCombobox: VCombobox,
31204
31572
  VComponentIcon: VComponentIcon,
@@ -31665,7 +32033,7 @@ function createVuetify$1() {
31665
32033
  };
31666
32034
  });
31667
32035
  }
31668
- const version$1 = "3.8.4-master.2025-05-12";
32036
+ const version$1 = "3.8.5-dev.2025-05-14";
31669
32037
  createVuetify$1.version = version$1;
31670
32038
 
31671
32039
  // Vue's inject() can only be used in setup
@@ -31963,7 +32331,7 @@ var index = /*#__PURE__*/Object.freeze({
31963
32331
 
31964
32332
  /* eslint-disable local-rules/sort-imports */
31965
32333
 
31966
- const version = "3.8.4-master.2025-05-12";
32334
+ const version = "3.8.5-dev.2025-05-14";
31967
32335
 
31968
32336
  /* eslint-disable local-rules/sort-imports */
31969
32337