@vuetify/nightly 3.8.9-dev.2025-06-11 → 3.8.9-dev.2025-06-13

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 (75) hide show
  1. package/CHANGELOG.md +12 -3
  2. package/dist/json/attributes.json +3441 -3169
  3. package/dist/json/importMap-labs.json +40 -36
  4. package/dist/json/importMap.json +166 -166
  5. package/dist/json/tags.json +74 -1
  6. package/dist/json/web-types.json +6884 -5821
  7. package/dist/vuetify-labs.cjs +357 -47
  8. package/dist/vuetify-labs.css +5881 -5870
  9. package/dist/vuetify-labs.d.ts +8448 -1672
  10. package/dist/vuetify-labs.esm.js +357 -47
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +357 -47
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +111 -47
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +5075 -5064
  17. package/dist/vuetify.d.ts +1499 -1302
  18. package/dist/vuetify.esm.js +111 -47
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +111 -47
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +1063 -1057
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VAutocomplete/VAutocomplete.d.ts +21 -7
  26. package/lib/components/VCombobox/VCombobox.d.ts +21 -7
  27. package/lib/components/VDatePicker/VDatePicker.d.ts +70 -5
  28. package/lib/components/VDatePicker/VDatePicker.js +10 -4
  29. package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
  30. package/lib/components/VKbd/VKbd.css +13 -2
  31. package/lib/components/VKbd/VKbd.d.ts +221 -0
  32. package/lib/components/VKbd/VKbd.js +55 -0
  33. package/lib/components/VKbd/VKbd.js.map +1 -0
  34. package/lib/components/VKbd/VKbd.sass +2 -1
  35. package/lib/components/VKbd/_variables.scss +12 -1
  36. package/lib/components/VKbd/index.d.ts +1 -95
  37. package/lib/components/VKbd/index.js +1 -4
  38. package/lib/components/VKbd/index.js.map +1 -1
  39. package/lib/components/VMenu/VMenu.d.ts +13 -0
  40. package/lib/components/VMenu/VMenu.js +2 -1
  41. package/lib/components/VMenu/VMenu.js.map +1 -1
  42. package/lib/components/VNumberInput/VNumberInput.d.ts +11 -0
  43. package/lib/components/VNumberInput/VNumberInput.js +37 -29
  44. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  45. package/lib/components/VSelect/VSelect.d.ts +33 -11
  46. package/lib/components/VSpeedDial/VSpeedDial.d.ts +13 -0
  47. package/lib/composables/locale.d.ts +5 -1
  48. package/lib/composables/locale.js.map +1 -1
  49. package/lib/composables/mask.d.ts +38 -0
  50. package/lib/composables/mask.js +183 -0
  51. package/lib/composables/mask.js.map +1 -0
  52. package/lib/composables/theme.js +3 -3
  53. package/lib/composables/theme.js.map +1 -1
  54. package/lib/entry-bundler.d.ts +1 -0
  55. package/lib/entry-bundler.js +1 -1
  56. package/lib/framework.d.ts +67 -63
  57. package/lib/framework.js +1 -1
  58. package/lib/labs/VMaskInput/VMaskInput.d.ts +6993 -0
  59. package/lib/labs/VMaskInput/VMaskInput.js +67 -0
  60. package/lib/labs/VMaskInput/VMaskInput.js.map +1 -0
  61. package/lib/labs/VMaskInput/index.d.ts +1 -0
  62. package/lib/labs/VMaskInput/index.js +2 -0
  63. package/lib/labs/VMaskInput/index.js.map +1 -0
  64. package/lib/labs/components.d.ts +1 -0
  65. package/lib/labs/components.js +1 -0
  66. package/lib/labs/components.js.map +1 -1
  67. package/lib/labs/entry-bundler.d.ts +1 -0
  68. package/lib/locale/adapters/vue-i18n.js +6 -1
  69. package/lib/locale/adapters/vue-i18n.js.map +1 -1
  70. package/lib/locale/adapters/vuetify.js +7 -1
  71. package/lib/locale/adapters/vuetify.js.map +1 -1
  72. package/lib/util/helpers.d.ts +2 -1
  73. package/lib/util/helpers.js +12 -7
  74. package/lib/util/helpers.js.map +1 -1
  75. package/package.json +1 -1
package/dist/vuetify.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.8.9-dev.2025-06-11
2
+ * Vuetify v3.8.9-dev.2025-06-13
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -515,18 +515,23 @@
515
515
  function isPrimitive(value) {
516
516
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint';
517
517
  }
518
- function extractNumber(text, decimalDigitsLimit) {
519
- const cleanText = text.split('').filter(x => /[\d\-.]/.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
518
+ function escapeForRegex(sign) {
519
+ return '\\^$*+?.()|{}[]'.includes(sign) ? `\\${sign}` : sign;
520
+ }
521
+ function extractNumber(text, decimalDigitsLimit, decimalSeparator) {
522
+ const onlyValidCharacters = new RegExp(`[\\d\\-${escapeForRegex(decimalSeparator)}]`);
523
+ const cleanText = text.split('').filter(x => onlyValidCharacters.test(x)).filter((x, i, all) => i === 0 && /[-]/.test(x) ||
520
524
  // sign allowed at the start
521
- x === '.' && i === all.indexOf('.') ||
525
+ x === decimalSeparator && i === all.indexOf(x) ||
522
526
  // decimal separator allowed only once
523
527
  /\d/.test(x)).join('');
524
528
  if (decimalDigitsLimit === 0) {
525
- return cleanText.split('.')[0];
529
+ return cleanText.split(decimalSeparator)[0];
526
530
  }
527
- if (decimalDigitsLimit !== null && /\.\d/.test(cleanText)) {
528
- const parts = cleanText.split('.');
529
- return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join('.');
531
+ const decimalPart = new RegExp(`${escapeForRegex(decimalSeparator)}\\d`);
532
+ if (decimalDigitsLimit !== null && decimalPart.test(cleanText)) {
533
+ const parts = cleanText.split(decimalSeparator);
534
+ return [parts[0], parts[1].substring(0, decimalDigitsLimit)].join(decimalSeparator);
530
535
  }
531
536
  return cleanText;
532
537
  }
@@ -2666,6 +2671,10 @@
2666
2671
  return numberFormat.format(value);
2667
2672
  };
2668
2673
  }
2674
+ function inferDecimalSeparator(current, fallback) {
2675
+ const format = createNumberFunction(current, fallback);
2676
+ return format(0.1).includes(',') ? ',' : '.';
2677
+ }
2669
2678
  function useProvided(props, prop, provided) {
2670
2679
  const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
2671
2680
 
@@ -2688,6 +2697,7 @@
2688
2697
  current,
2689
2698
  fallback,
2690
2699
  messages,
2700
+ decimalSeparator: vue.toRef(() => inferDecimalSeparator(current, fallback)),
2691
2701
  t: createTranslateFunction(current, fallback, messages),
2692
2702
  n: createNumberFunction(current, fallback),
2693
2703
  provide: createProvideFunction({
@@ -2710,6 +2720,7 @@
2710
2720
  current,
2711
2721
  fallback,
2712
2722
  messages,
2723
+ decimalSeparator: vue.toRef(() => options?.decimalSeparator ?? inferDecimalSeparator(current, fallback)),
2713
2724
  t: createTranslateFunction(current, fallback, messages),
2714
2725
  n: createNumberFunction(current, fallback),
2715
2726
  provide: createProvideFunction({
@@ -2874,8 +2885,8 @@
2874
2885
  'activated-opacity': 0.12,
2875
2886
  'pressed-opacity': 0.12,
2876
2887
  'dragged-opacity': 0.08,
2877
- 'theme-kbd': '#212529',
2878
- 'theme-on-kbd': '#FFFFFF',
2888
+ 'theme-kbd': '#EEEEEE',
2889
+ 'theme-on-kbd': '#000000',
2879
2890
  'theme-code': '#F5F5F5',
2880
2891
  'theme-on-code': '#000000'
2881
2892
  }
@@ -2911,7 +2922,7 @@
2911
2922
  'activated-opacity': 0.12,
2912
2923
  'pressed-opacity': 0.16,
2913
2924
  'dragged-opacity': 0.08,
2914
- 'theme-kbd': '#212529',
2925
+ 'theme-kbd': '#424242',
2915
2926
  'theme-on-kbd': '#FFFFFF',
2916
2927
  'theme-code': '#343434',
2917
2928
  'theme-on-code': '#CCCCCC'
@@ -11912,6 +11923,7 @@
11912
11923
  // disableKeys: Boolean,
11913
11924
  id: String,
11914
11925
  submenu: Boolean,
11926
+ disableInitialFocus: Boolean,
11915
11927
  ...omit(makeVOverlayProps({
11916
11928
  closeDelay: 250,
11917
11929
  closeOnContentClick: true,
@@ -11986,7 +11998,7 @@
11986
11998
  vue.watch(isActive, val => {
11987
11999
  if (val) {
11988
12000
  parent?.register();
11989
- if (IN_BROWSER) {
12001
+ if (IN_BROWSER && !props.disableInitialFocus) {
11990
12002
  document.addEventListener('focusin', onFocusIn, {
11991
12003
  once: true
11992
12004
  });
@@ -23287,7 +23299,9 @@
23287
23299
  "max": maxDate.value,
23288
23300
  "year": year.value,
23289
23301
  "allowedMonths": allowedMonths
23290
- }), null) : viewMode.value === 'year' ? vue.createVNode(VDatePickerYears, vue.mergeProps({
23302
+ }), {
23303
+ ...pick(slots, ['month'])
23304
+ }) : viewMode.value === 'year' ? vue.createVNode(VDatePickerYears, vue.mergeProps({
23291
23305
  "key": "date-picker-years"
23292
23306
  }, datePickerYearsProps, {
23293
23307
  "modelValue": year.value,
@@ -23295,7 +23309,9 @@
23295
23309
  "min": minDate.value,
23296
23310
  "max": maxDate.value,
23297
23311
  "allowedYears": allowedYears
23298
- }), null) : vue.createVNode(VDatePickerMonth, vue.mergeProps({
23312
+ }), {
23313
+ ...pick(slots, ['year'])
23314
+ }) : vue.createVNode(VDatePickerMonth, vue.mergeProps({
23299
23315
  "key": "date-picker-month"
23300
23316
  }, datePickerMonthProps, {
23301
23317
  "modelValue": model.value,
@@ -23306,7 +23322,9 @@
23306
23322
  "onUpdate:year": [$event => year.value = $event, onUpdateYear],
23307
23323
  "min": minDate.value,
23308
23324
  "max": maxDate.value
23309
- }), null)]
23325
+ }), {
23326
+ ...pick(slots, ['day'])
23327
+ })]
23310
23328
  })]),
23311
23329
  actions: slots.actions
23312
23330
  });
@@ -24616,8 +24634,47 @@
24616
24634
  }
24617
24635
  });
24618
24636
 
24619
- // Styles
24620
- const VKbd = createSimpleFunctional('v-kbd', 'kbd');
24637
+ const makeVKbdProps = propsFactory({
24638
+ ...makeBorderProps(),
24639
+ ...makeComponentProps(),
24640
+ ...makeRoundedProps(),
24641
+ ...makeTagProps({
24642
+ tag: 'kbd'
24643
+ }),
24644
+ ...makeThemeProps(),
24645
+ ...makeElevationProps(),
24646
+ color: String
24647
+ }, 'VKbd');
24648
+ const VKbd = genericComponent()({
24649
+ name: 'VKbd',
24650
+ props: makeVKbdProps(),
24651
+ setup(props, _ref) {
24652
+ let {
24653
+ slots
24654
+ } = _ref;
24655
+ const {
24656
+ themeClasses
24657
+ } = provideTheme(props);
24658
+ const {
24659
+ borderClasses
24660
+ } = useBorder(props);
24661
+ const {
24662
+ roundedClasses
24663
+ } = useRounded(props);
24664
+ const {
24665
+ backgroundColorClasses,
24666
+ backgroundColorStyles
24667
+ } = useBackgroundColor(() => props.color);
24668
+ const {
24669
+ elevationClasses
24670
+ } = useElevation(props);
24671
+ useRender(() => vue.createVNode(props.tag, {
24672
+ "class": vue.normalizeClass(['v-kbd', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class]),
24673
+ "style": vue.normalizeStyle([backgroundColorStyles.value, props.style])
24674
+ }, slots));
24675
+ return {};
24676
+ }
24677
+ });
24621
24678
 
24622
24679
  const makeVLayoutProps = propsFactory({
24623
24680
  ...makeComponentProps(),
@@ -25459,6 +25516,10 @@
25459
25516
  type: Number,
25460
25517
  default: null
25461
25518
  },
25519
+ decimalSeparator: {
25520
+ type: String,
25521
+ validator: v => !v || v.length === 1
25522
+ },
25462
25523
  ...omit(makeVTextFieldProps(), ['modelValue', 'validationValue'])
25463
25524
  }, 'VNumberInput');
25464
25525
  const VNumberInput = genericComponent()({
@@ -25484,21 +25545,24 @@
25484
25545
  const form = useForm(props);
25485
25546
  const controlsDisabled = vue.computed(() => form.isDisabled.value || form.isReadonly.value);
25486
25547
  const isFocused = vue.shallowRef(props.focused);
25548
+ const {
25549
+ decimalSeparator: decimalSeparatorFromLocale
25550
+ } = useLocale();
25551
+ const decimalSeparator = vue.computed(() => props.decimalSeparator?.[0] || decimalSeparatorFromLocale.value);
25487
25552
  function correctPrecision(val) {
25488
25553
  let precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.precision;
25489
- if (precision == null) {
25490
- return String(val);
25491
- }
25492
- let fixed = val.toFixed(precision);
25493
- if (isFocused.value) {
25494
- return Number(fixed).toString(); // trim zeros
25554
+ let trim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
25555
+ const fixed = precision == null ? String(val) : val.toFixed(precision);
25556
+ if (isFocused.value && trim) {
25557
+ return Number(fixed).toString() // trim zeros
25558
+ .replace('.', decimalSeparator.value);
25495
25559
  }
25496
- if ((props.minFractionDigits ?? precision) < precision) {
25497
- const trimLimit = precision - props.minFractionDigits;
25498
- const [baseDigits, fractionDigits] = fixed.split('.');
25499
- fixed = [baseDigits, fractionDigits.replace(new RegExp(`0{1,${trimLimit}}$`), '')].filter(Boolean).join('.');
25560
+ if (props.minFractionDigits === null || precision !== null && precision < props.minFractionDigits) {
25561
+ return fixed.replace('.', decimalSeparator.value);
25500
25562
  }
25501
- return fixed;
25563
+ let [baseDigits, fractionDigits] = fixed.split('.');
25564
+ fractionDigits = (fractionDigits ?? '').padEnd(props.minFractionDigits, '0').replace(new RegExp(`(?<=\\d{${props.minFractionDigits}})0`, 'g'), '');
25565
+ return [baseDigits, fractionDigits].filter(Boolean).join(decimalSeparator.value);
25502
25566
  }
25503
25567
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
25504
25568
  const _inputText = vue.shallowRef(null);
@@ -25515,8 +25579,11 @@
25515
25579
  if (val === null || val === '') {
25516
25580
  model.value = null;
25517
25581
  _inputText.value = null;
25518
- } else if (!isNaN(Number(val)) && Number(val) <= props.max && Number(val) >= props.min) {
25519
- model.value = Number(val);
25582
+ return;
25583
+ }
25584
+ const parsedValue = Number(val.replace(decimalSeparator.value, '.'));
25585
+ if (!isNaN(parsedValue) && parsedValue <= props.max && parsedValue >= props.min) {
25586
+ model.value = parsedValue;
25520
25587
  _inputText.value = val;
25521
25588
  }
25522
25589
  }
@@ -25587,24 +25654,24 @@
25587
25654
  selectionEnd
25588
25655
  } = inputElement ?? {};
25589
25656
  const potentialNewInputVal = existingTxt ? existingTxt.slice(0, selectionStart) + e.data + existingTxt.slice(selectionEnd) : e.data;
25590
- const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision);
25657
+ const potentialNewNumber = extractNumber(potentialNewInputVal, props.precision, decimalSeparator.value);
25591
25658
 
25592
- // Only numbers, "-", "." are allowed
25593
- // AND "-", "." are allowed only once
25594
- // AND "-" is only allowed at the start
25595
- if (!/^-?(\d+(\.\d*)?|(\.\d+)|\d*|\.)$/.test(potentialNewInputVal)) {
25659
+ // Allow only numbers, "-" and {decimal separator}
25660
+ // Allow "-" and {decimal separator} only once
25661
+ // Allow "-" only at the start
25662
+ if (!new RegExp(`^-?\\d*${escapeForRegex(decimalSeparator.value)}?\\d*$`).test(potentialNewInputVal)) {
25596
25663
  e.preventDefault();
25597
25664
  inputElement.value = potentialNewNumber;
25598
25665
  }
25599
25666
  if (props.precision == null) return;
25600
25667
 
25601
25668
  // Ignore decimal digits above precision limit
25602
- if (potentialNewInputVal.split('.')[1]?.length > props.precision) {
25669
+ if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {
25603
25670
  e.preventDefault();
25604
25671
  inputElement.value = potentialNewNumber;
25605
25672
  }
25606
25673
  // Ignore decimal separator when precision = 0
25607
- if (props.precision === 0 && potentialNewInputVal.includes('.')) {
25674
+ if (props.precision === 0 && potentialNewInputVal.includes(decimalSeparator.value)) {
25608
25675
  e.preventDefault();
25609
25676
  inputElement.value = potentialNewNumber;
25610
25677
  }
@@ -25656,19 +25723,16 @@
25656
25723
  if (controlsDisabled.value) return;
25657
25724
  if (!vTextFieldRef.value) return;
25658
25725
  const actualText = vTextFieldRef.value.value;
25659
- if (actualText && !isNaN(Number(actualText))) {
25660
- inputText.value = correctPrecision(clamp(Number(actualText), props.min, props.max));
25726
+ const parsedValue = Number(actualText.replace(decimalSeparator.value, '.'));
25727
+ if (actualText && !isNaN(parsedValue)) {
25728
+ inputText.value = correctPrecision(clamp(parsedValue, props.min, props.max));
25661
25729
  } else {
25662
25730
  inputText.value = null;
25663
25731
  }
25664
25732
  }
25665
25733
  function formatInputValue() {
25666
25734
  if (controlsDisabled.value) return;
25667
- if (model.value === null || isNaN(model.value)) {
25668
- inputText.value = null;
25669
- return;
25670
- }
25671
- inputText.value = correctPrecision(model.value);
25735
+ inputText.value = model.value !== null && !isNaN(model.value) ? correctPrecision(model.value, props.precision, false) : null;
25672
25736
  }
25673
25737
  function trimDecimalZeros() {
25674
25738
  if (controlsDisabled.value) return;
@@ -25676,7 +25740,7 @@
25676
25740
  inputText.value = null;
25677
25741
  return;
25678
25742
  }
25679
- inputText.value = model.value.toString();
25743
+ inputText.value = model.value.toString().replace('.', decimalSeparator.value);
25680
25744
  }
25681
25745
  function onFocus() {
25682
25746
  trimDecimalZeros();
@@ -29716,7 +29780,7 @@
29716
29780
  };
29717
29781
  });
29718
29782
  }
29719
- const version$1 = "3.8.9-dev.2025-06-11";
29783
+ const version$1 = "3.8.9-dev.2025-06-13";
29720
29784
  createVuetify$1.version = version$1;
29721
29785
 
29722
29786
  // Vue's inject() can only be used in setup
@@ -29741,7 +29805,7 @@
29741
29805
  ...options
29742
29806
  });
29743
29807
  };
29744
- const version = "3.8.9-dev.2025-06-11";
29808
+ const version = "3.8.9-dev.2025-06-13";
29745
29809
  createVuetify.version = version;
29746
29810
 
29747
29811
  exports.blueprints = index;