vuetify 3.10.5 → 3.10.6

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 (89) hide show
  1. package/README.md +0 -6
  2. package/dist/json/attributes.json +3568 -3592
  3. package/dist/json/importMap-labs.json +24 -24
  4. package/dist/json/importMap.json +152 -152
  5. package/dist/json/tags.json +3 -9
  6. package/dist/json/web-types.json +6916 -6969
  7. package/dist/vuetify-labs.cjs +178 -72
  8. package/dist/vuetify-labs.css +4389 -4339
  9. package/dist/vuetify-labs.d.ts +108 -163
  10. package/dist/vuetify-labs.esm.js +178 -72
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +178 -72
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +159 -62
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +4349 -4321
  17. package/dist/vuetify.d.ts +108 -128
  18. package/dist/vuetify.esm.js +159 -62
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +159 -62
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +113 -102
  24. package/dist/vuetify.min.js.map +1 -1
  25. package/lib/components/VAutocomplete/VAutocomplete.d.ts +0 -61
  26. package/lib/components/VAutocomplete/VAutocomplete.js +13 -11
  27. package/lib/components/VAutocomplete/VAutocomplete.js.map +1 -1
  28. package/lib/components/VChipGroup/VChipGroup.d.ts +37 -0
  29. package/lib/components/VChipGroup/VChipGroup.js +3 -1
  30. package/lib/components/VChipGroup/VChipGroup.js.map +1 -1
  31. package/lib/components/VCombobox/VCombobox.d.ts +6 -67
  32. package/lib/components/VCombobox/VCombobox.js +26 -28
  33. package/lib/components/VCombobox/VCombobox.js.map +1 -1
  34. package/lib/components/VCounter/VCounter.css +1 -0
  35. package/lib/components/VCounter/VCounter.sass +1 -0
  36. package/lib/components/VDatePicker/VDatePicker.js +1 -1
  37. package/lib/components/VDatePicker/VDatePicker.js.map +1 -1
  38. package/lib/components/VList/VListItem.css +14 -12
  39. package/lib/components/VList/VListItem.js +4 -2
  40. package/lib/components/VList/VListItem.js.map +1 -1
  41. package/lib/components/VList/VListItem.sass +20 -18
  42. package/lib/components/VMenu/VMenu.js +22 -4
  43. package/lib/components/VMenu/VMenu.js.map +1 -1
  44. package/lib/components/VNumberInput/VNumberInput.css +8 -0
  45. package/lib/components/VNumberInput/VNumberInput.js +5 -2
  46. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  47. package/lib/components/VNumberInput/VNumberInput.sass +10 -4
  48. package/lib/components/VSkeletonLoader/VSkeletonLoader.css +17 -0
  49. package/lib/components/VSkeletonLoader/VSkeletonLoader.js +3 -3
  50. package/lib/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  51. package/lib/components/VSkeletonLoader/VSkeletonLoader.sass +7 -0
  52. package/lib/components/VSlideGroup/VSlideGroup.d.ts +25 -0
  53. package/lib/components/VSlideGroup/VSlideGroup.js +5 -1
  54. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  55. package/lib/components/VTabs/VTabs.d.ts +25 -0
  56. package/lib/components/VTextField/VTextField.js +0 -3
  57. package/lib/components/VTextField/VTextField.js.map +1 -1
  58. package/lib/components/VTextarea/VTextarea.css +2 -2
  59. package/lib/components/VTextarea/VTextarea.js +20 -1
  60. package/lib/components/VTextarea/VTextarea.js.map +1 -1
  61. package/lib/components/VTextarea/VTextarea.sass +4 -2
  62. package/lib/components/VWindow/VWindow.js +43 -3
  63. package/lib/components/VWindow/VWindow.js.map +1 -1
  64. package/lib/composables/date/date.js +1 -1
  65. package/lib/composables/date/date.js.map +1 -1
  66. package/lib/composables/group.js +1 -1
  67. package/lib/composables/group.js.map +1 -1
  68. package/lib/composables/nested/nested.js +12 -2
  69. package/lib/composables/nested/nested.js.map +1 -1
  70. package/lib/composables/virtual.js +2 -2
  71. package/lib/composables/virtual.js.map +1 -1
  72. package/lib/entry-bundler.js +1 -1
  73. package/lib/framework.d.ts +54 -54
  74. package/lib/framework.js +1 -1
  75. package/lib/labs/VColorInput/VColorInput.d.ts +0 -40
  76. package/lib/labs/VColorInput/VColorInput.js +2 -2
  77. package/lib/labs/VColorInput/VColorInput.js.map +1 -1
  78. package/lib/labs/VDateInput/VDateInput.d.ts +0 -30
  79. package/lib/labs/VDateInput/VDateInput.js +16 -7
  80. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  81. package/lib/labs/VIconBtn/VIconBtn.css +22 -0
  82. package/lib/labs/VIconBtn/VIconBtn.scss +32 -0
  83. package/lib/labs/VMaskInput/VMaskInput.js +1 -1
  84. package/lib/labs/VMaskInput/VMaskInput.js.map +1 -1
  85. package/lib/labs/rules/rules.js +1 -1
  86. package/lib/labs/rules/rules.js.map +1 -1
  87. package/lib/util/helpers.js +4 -2
  88. package/lib/util/helpers.js.map +1 -1
  89. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.10.5
2
+ * Vuetify v3.10.6
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -472,8 +472,10 @@
472
472
  }
473
473
  function focusableChildren(el) {
474
474
  let filterByTabIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
475
- const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled])`).join(', ');
476
- return [...el.querySelectorAll(targets)];
475
+ const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', 'details:not(:has(> summary))', 'details > summary', '[tabindex]', '[contenteditable]:not([contenteditable="false"])', 'audio[controls]', 'video[controls]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled], [inert])`).join(', ');
476
+ return [...el.querySelectorAll(targets)].filter(x => !x.closest('[inert]')) // does not have inert parent
477
+ .filter(x => !!x.offsetParent || x.getClientRects().length > 0) // is rendered
478
+ .filter(x => !x.parentElement?.closest('details:not([open])') || x.tagName === 'SUMMARY' && x.parentElement?.tagName === 'DETAILS');
477
479
  }
478
480
  function getNextElement(elements, location, condition) {
479
481
  let _el;
@@ -4547,7 +4549,7 @@
4547
4549
  function unregister() {
4548
4550
  group?.unregister(id);
4549
4551
  }
4550
- vue.onMounted(() => register());
4552
+ register();
4551
4553
  vue.onBeforeUnmount(() => unregister());
4552
4554
  const isSelected = vue.computed(() => {
4553
4555
  return group.isSelected(id);
@@ -8097,6 +8099,10 @@
8097
8099
  const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
8098
8100
  const makeVSlideGroupProps = propsFactory({
8099
8101
  centerActive: Boolean,
8102
+ scrollToActive: {
8103
+ type: Boolean,
8104
+ default: true
8105
+ },
8100
8106
  contentClass: null,
8101
8107
  direction: {
8102
8108
  type: String,
@@ -8185,7 +8191,7 @@
8185
8191
  contentSize.value = contentRect.value[sizeProperty];
8186
8192
  isOverflowing.value = containerSize.value + 1 < contentSize.value;
8187
8193
  }
8188
- if (firstSelectedIndex.value >= 0 && contentRef.el) {
8194
+ if (props.scrollToActive && firstSelectedIndex.value >= 0 && contentRef.el) {
8189
8195
  // TODO: Is this too naive? Should we store element references in group composable?
8190
8196
  const selectedElement = contentRef.el.children[lastSelectedIndex.value];
8191
8197
  scrollToChildren(selectedElement, props.centerActive);
@@ -8454,7 +8460,9 @@
8454
8460
  type: Function,
8455
8461
  default: deepEqual
8456
8462
  },
8457
- ...makeVSlideGroupProps(),
8463
+ ...makeVSlideGroupProps({
8464
+ scrollToActive: false
8465
+ }),
8458
8466
  ...makeComponentProps(),
8459
8467
  ...makeGroupProps({
8460
8468
  selectedClass: 'v-chip--selected'
@@ -9553,7 +9561,9 @@
9553
9561
  };
9554
9562
  vue.onBeforeMount(() => {
9555
9563
  if (!parent.isGroupActivator) {
9556
- parent.root.register(computedId.value, parent.id.value, vue.toValue(isDisabled), isGroup);
9564
+ vue.nextTick(() => {
9565
+ parent.root.register(computedId.value, parent.id.value, vue.toValue(isDisabled), isGroup);
9566
+ });
9557
9567
  }
9558
9568
  });
9559
9569
  vue.onBeforeUnmount(() => {
@@ -9561,6 +9571,14 @@
9561
9571
  parent.root.unregister(computedId.value);
9562
9572
  }
9563
9573
  });
9574
+ vue.watch(computedId, (val, oldVal) => {
9575
+ if (!parent.isGroupActivator) {
9576
+ parent.root.unregister(oldVal);
9577
+ vue.nextTick(() => {
9578
+ parent.root.register(val, parent.id.value, vue.toValue(isDisabled), isGroup);
9579
+ });
9580
+ }
9581
+ });
9564
9582
  isGroup && vue.provide(VNestedSymbol, item);
9565
9583
  return item;
9566
9584
  };
@@ -9811,7 +9829,9 @@
9811
9829
  handleActiveLink();
9812
9830
  });
9813
9831
  vue.onBeforeMount(() => {
9814
- if (link.isActive?.value) handleActiveLink();
9832
+ if (link.isActive?.value) {
9833
+ vue.nextTick(() => handleActiveLink());
9834
+ }
9815
9835
  });
9816
9836
  function handleActiveLink() {
9817
9837
  if (parent.value != null) {
@@ -12059,25 +12079,41 @@
12059
12079
  document.removeEventListener('focusin', onFocusIn);
12060
12080
  });
12061
12081
  vue.onDeactivated(() => isActive.value = false);
12082
+ let focusTrapSuppressed = false;
12083
+ let focusTrapSuppressionTimeout = -1;
12084
+ async function onPointerdown() {
12085
+ focusTrapSuppressed = true;
12086
+ focusTrapSuppressionTimeout = window.setTimeout(() => {
12087
+ focusTrapSuppressed = false;
12088
+ }, 100);
12089
+ }
12062
12090
  async function onFocusIn(e) {
12063
12091
  const before = e.relatedTarget;
12064
12092
  const after = e.target;
12065
12093
  await vue.nextTick();
12066
12094
  if (isActive.value && before !== after && overlay.value?.contentEl &&
12067
- // We're the topmost menu
12068
- overlay.value?.globalTop &&
12095
+ // We're the menu without open submenus or overlays
12096
+ overlay.value?.localTop &&
12069
12097
  // It isn't the document or the menu body
12070
12098
  ![document, overlay.value.contentEl].includes(after) &&
12071
12099
  // It isn't inside the menu body
12072
12100
  !overlay.value.contentEl.contains(after)) {
12073
- const focusable = focusableChildren(overlay.value.contentEl);
12074
- focusable[0]?.focus();
12101
+ if (focusTrapSuppressed) {
12102
+ if (!props.openOnHover || !overlay.value.activatorEl?.contains(after)) {
12103
+ isActive.value = false;
12104
+ }
12105
+ } else {
12106
+ const focusable = focusableChildren(overlay.value.contentEl);
12107
+ focusable[0]?.focus();
12108
+ document.removeEventListener('pointerdown', onPointerdown);
12109
+ }
12075
12110
  }
12076
12111
  }
12077
12112
  vue.watch(isActive, val => {
12078
12113
  if (val) {
12079
12114
  parent?.register();
12080
12115
  if (IN_BROWSER && !props.disableInitialFocus) {
12116
+ document.addEventListener('pointerdown', onPointerdown);
12081
12117
  document.addEventListener('focusin', onFocusIn, {
12082
12118
  once: true
12083
12119
  });
@@ -12085,6 +12121,8 @@
12085
12121
  } else {
12086
12122
  parent?.unregister();
12087
12123
  if (IN_BROWSER) {
12124
+ clearTimeout(focusTrapSuppressionTimeout);
12125
+ document.removeEventListener('pointerdown', onPointerdown);
12088
12126
  document.removeEventListener('focusin', onFocusIn);
12089
12127
  }
12090
12128
  }
@@ -12678,7 +12716,6 @@
12678
12716
  e.stopPropagation();
12679
12717
  onFocus();
12680
12718
  vue.nextTick(() => {
12681
- model.value = null;
12682
12719
  reset();
12683
12720
  callEvent(props['onClick:clear'], e);
12684
12721
  });
@@ -12733,8 +12770,6 @@
12733
12770
  "onMousedown": onControlMousedown,
12734
12771
  "onClick": onControlClick,
12735
12772
  "onClick:clear": e => onClear(e, reset),
12736
- "onClick:prependInner": props['onClick:prependInner'],
12737
- "onClick:appendInner": props['onClick:appendInner'],
12738
12773
  "role": props.role
12739
12774
  }, omit(fieldProps, ['onClick:clear']), {
12740
12775
  "id": id.value,
@@ -12910,7 +12945,7 @@
12910
12945
  const start = performance.now();
12911
12946
  offsets[0] = 0;
12912
12947
  const length = items.value.length;
12913
- for (let i = 1; i <= length - 1; i++) {
12948
+ for (let i = 1; i <= length; i++) {
12914
12949
  offsets[i] = (offsets[i - 1] || 0) + getSize(i - 1);
12915
12950
  }
12916
12951
  updateTime.value = Math.max(updateTime.value, performance.now() - start);
@@ -12945,7 +12980,7 @@
12945
12980
  }
12946
12981
  }
12947
12982
  function calculateOffset(index) {
12948
- index = clamp(index, 0, items.value.length - 1);
12983
+ index = clamp(index, 0, items.value.length);
12949
12984
  const whole = Math.floor(index);
12950
12985
  const fraction = index % 1;
12951
12986
  const next = whole + 1;
@@ -13950,10 +13985,7 @@
13950
13985
  ...omit(makeVTextFieldProps({
13951
13986
  modelValue: null,
13952
13987
  role: 'combobox'
13953
- }), ['validationValue', 'dirty', 'appendInnerIcon']),
13954
- ...makeTransitionProps({
13955
- transition: false
13956
- })
13988
+ }), ['validationValue', 'dirty', 'appendInnerIcon'])
13957
13989
  }, 'VAutocomplete');
13958
13990
  const VAutocomplete = genericComponent()({
13959
13991
  name: 'VAutocomplete',
@@ -13978,6 +14010,7 @@
13978
14010
  const vMenuRef = vue.ref();
13979
14011
  const vVirtualScrollRef = vue.ref();
13980
14012
  const selectionIndex = vue.shallowRef(-1);
14013
+ const _searchLock = vue.shallowRef(null);
13981
14014
  const {
13982
14015
  items,
13983
14016
  transformIn,
@@ -13999,9 +14032,9 @@
13999
14032
  const {
14000
14033
  filteredItems,
14001
14034
  getMatches
14002
- } = useFilter(props, items, () => isPristine.value ? '' : search.value);
14035
+ } = useFilter(props, items, () => _searchLock.value ?? (isPristine.value ? '' : search.value));
14003
14036
  const displayItems = vue.computed(() => {
14004
- if (props.hideSelected) {
14037
+ if (props.hideSelected && _searchLock.value === null) {
14005
14038
  return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
14006
14039
  }
14007
14040
  return filteredItems.value;
@@ -14132,6 +14165,7 @@
14132
14165
  isPristine.value = true;
14133
14166
  vTextFieldRef.value?.focus();
14134
14167
  }
14168
+ _searchLock.value = null;
14135
14169
  }
14136
14170
  function onFocusin(e) {
14137
14171
  isFocused.value = true;
@@ -14167,6 +14201,7 @@
14167
14201
  } else {
14168
14202
  const add = set !== false;
14169
14203
  model.value = add ? [item] : [];
14204
+ _searchLock.value = isPristine.value ? '' : search.value ?? '';
14170
14205
  search.value = add && !hasSelectionSlot.value ? item.title : '';
14171
14206
 
14172
14207
  // watch for search watcher to trigger
@@ -14186,6 +14221,9 @@
14186
14221
  } else {
14187
14222
  if (!props.multiple && search.value == null) model.value = [];
14188
14223
  menu.value = false;
14224
+ if (!isPristine.value && search.value) {
14225
+ _searchLock.value = search.value;
14226
+ }
14189
14227
  search.value = '';
14190
14228
  selectionIndex.value = -1;
14191
14229
  }
@@ -14195,13 +14233,14 @@
14195
14233
  if (val) menu.value = true;
14196
14234
  isPristine.value = !val;
14197
14235
  });
14198
- vue.watch(menu, () => {
14199
- if (!props.hideSelected && menu.value && model.value.length) {
14236
+ vue.watch(menu, val => {
14237
+ if (!props.hideSelected && val && model.value.length && isPristine.value) {
14200
14238
  const index = displayItems.value.findIndex(item => model.value.some(s => item.value === s.value));
14201
14239
  IN_BROWSER && window.requestAnimationFrame(() => {
14202
14240
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
14203
14241
  });
14204
14242
  }
14243
+ if (val) _searchLock.value = null;
14205
14244
  });
14206
14245
  vue.watch(items, (newVal, oldVal) => {
14207
14246
  if (menu.value) return;
@@ -14252,7 +14291,6 @@
14252
14291
  "maxHeight": 310,
14253
14292
  "openOnClick": false,
14254
14293
  "closeOnContentClick": false,
14255
- "transition": props.transition,
14256
14294
  "onAfterEnter": onAfterEnter,
14257
14295
  "onAfterLeave": onAfterLeave
14258
14296
  }, props.menuProps), {
@@ -15680,7 +15718,21 @@
15680
15718
  const activeIndex = vue.computed(() => {
15681
15719
  return group.items.value.findIndex(item => group.selected.value.includes(item.id));
15682
15720
  });
15721
+
15722
+ // Fix for https://github.com/vuetifyjs/vuetify/issues/18447
15683
15723
  vue.watch(activeIndex, (newVal, oldVal) => {
15724
+ let scrollableParent;
15725
+ const savedScrollPosition = {
15726
+ x: 0,
15727
+ y: 0
15728
+ };
15729
+ if (IN_BROWSER && oldVal >= 0) {
15730
+ scrollableParent = getScrollParent(rootRef.value);
15731
+
15732
+ // Save current scroll position
15733
+ savedScrollPosition.x = scrollableParent.scrollLeft;
15734
+ savedScrollPosition.y = scrollableParent.scrollTop;
15735
+ }
15684
15736
  const itemsLength = group.items.value.length;
15685
15737
  const lastIndex = itemsLength - 1;
15686
15738
  if (itemsLength <= 2) {
@@ -15692,7 +15744,32 @@
15692
15744
  } else {
15693
15745
  isReversed.value = newVal < oldVal;
15694
15746
  }
15695
- });
15747
+ vue.nextTick(() => {
15748
+ if (!IN_BROWSER || !scrollableParent) return;
15749
+ const currentScrollY = scrollableParent.scrollTop;
15750
+ if (currentScrollY !== savedScrollPosition.y) {
15751
+ scrollableParent.scrollTo({
15752
+ left: savedScrollPosition.x,
15753
+ top: savedScrollPosition.y,
15754
+ behavior: 'instant'
15755
+ });
15756
+ }
15757
+ requestAnimationFrame(() => {
15758
+ if (!scrollableParent) return;
15759
+ const rafScrollY = scrollableParent.scrollTop;
15760
+ if (rafScrollY !== savedScrollPosition.y) {
15761
+ scrollableParent.scrollTo({
15762
+ left: savedScrollPosition.x,
15763
+ top: savedScrollPosition.y,
15764
+ behavior: 'instant'
15765
+ });
15766
+ }
15767
+ });
15768
+ });
15769
+ }, {
15770
+ flush: 'sync'
15771
+ }); // Run synchronously before DOM updates
15772
+
15696
15773
  vue.provide(VWindowSymbol, {
15697
15774
  transition,
15698
15775
  isReversed,
@@ -18597,7 +18674,7 @@
18597
18674
  };
18598
18675
  }
18599
18676
  function createDateRange(adapter, start, stop) {
18600
- const diff = adapter.getDiff(adapter.endOfDay(stop ?? start), adapter.startOfDay(start), 'days');
18677
+ const diff = adapter.getDiff(new Date(`${adapter.toISO(stop ?? start)}T00:00:00Z`), new Date(`${adapter.toISO(start)}T00:00:00Z`), 'days');
18601
18678
  const datesInRange = [start];
18602
18679
  for (let i = 1; i < diff; i++) {
18603
18680
  const nextDate = adapter.addDays(start, i);
@@ -19280,10 +19357,7 @@
19280
19357
  ...omit(makeVTextFieldProps({
19281
19358
  modelValue: null,
19282
19359
  role: 'combobox'
19283
- }), ['validationValue', 'dirty', 'appendInnerIcon']),
19284
- ...makeTransitionProps({
19285
- transition: false
19286
- })
19360
+ }), ['validationValue', 'dirty', 'appendInnerIcon'])
19287
19361
  }, 'VCombobox');
19288
19362
  const VCombobox = genericComponent()({
19289
19363
  name: 'VCombobox',
@@ -19327,13 +19401,16 @@
19327
19401
  const hasChips = vue.computed(() => !!(props.chips || slots.chip));
19328
19402
  const hasSelectionSlot = vue.computed(() => hasChips.value || !!slots.selection);
19329
19403
  const _search = vue.shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
19404
+ const _searchLock = vue.shallowRef(null);
19330
19405
  const search = vue.computed({
19331
19406
  get: () => {
19332
19407
  return _search.value;
19333
19408
  },
19334
19409
  set: async val => {
19335
19410
  _search.value = val ?? '';
19336
- if (!props.multiple && !hasSelectionSlot.value) {
19411
+ if (val === null || val === '' && !props.multiple && !hasSelectionSlot.value) {
19412
+ model.value = [];
19413
+ } else if (!props.multiple && !hasSelectionSlot.value) {
19337
19414
  model.value = [transformItem$3(props, val)];
19338
19415
  vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
19339
19416
  }
@@ -19361,9 +19438,9 @@
19361
19438
  const {
19362
19439
  filteredItems,
19363
19440
  getMatches
19364
- } = useFilter(props, items, () => props.alwaysFilter || !isPristine.value ? search.value : '');
19441
+ } = useFilter(props, items, () => _searchLock.value ?? (props.alwaysFilter || !isPristine.value ? search.value : ''));
19365
19442
  const displayItems = vue.computed(() => {
19366
- if (props.hideSelected) {
19443
+ if (props.hideSelected && _searchLock.value === null) {
19367
19444
  return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
19368
19445
  }
19369
19446
  return filteredItems.value;
@@ -19444,22 +19521,19 @@
19444
19521
  if (['Escape'].includes(e.key)) {
19445
19522
  menu.value = false;
19446
19523
  }
19447
- if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
19448
- if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
19449
- let {
19450
- value
19451
- } = _ref2;
19452
- return value === displayItems.value[0].value;
19453
- })) {
19454
- select(filteredItems.value[0]);
19455
- }
19456
- isPristine.value = true;
19524
+ if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
19525
+ let {
19526
+ value
19527
+ } = _ref2;
19528
+ return value === displayItems.value[0].value;
19529
+ })) {
19530
+ select(filteredItems.value[0]);
19457
19531
  }
19458
19532
  if (e.key === 'ArrowDown' && highlightFirst.value) {
19459
19533
  listRef.value?.focus('next');
19460
19534
  }
19461
19535
  if (e.key === 'Enter' && search.value) {
19462
- select(transformItem$3(props, search.value));
19536
+ select(transformItem$3(props, search.value), true, true);
19463
19537
  if (hasSelectionSlot.value) _search.value = '';
19464
19538
  }
19465
19539
  if (['Backspace', 'Delete'].includes(e.key)) {
@@ -19507,10 +19581,12 @@
19507
19581
  isPristine.value = true;
19508
19582
  vTextFieldRef.value?.focus();
19509
19583
  }
19584
+ _searchLock.value = null;
19510
19585
  }
19511
19586
  /** @param set - null means toggle */
19512
19587
  function select(item) {
19513
19588
  let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19589
+ let keepMenu = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
19514
19590
  if (!item || item.props.disabled) return;
19515
19591
  if (props.multiple) {
19516
19592
  const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value));
@@ -19528,11 +19604,14 @@
19528
19604
  } else {
19529
19605
  const add = set !== false;
19530
19606
  model.value = add ? [item] : [];
19607
+ if ((!isPristine.value || props.alwaysFilter) && _search.value) {
19608
+ _searchLock.value = _search.value;
19609
+ }
19531
19610
  _search.value = add && !hasSelectionSlot.value ? item.title : '';
19532
19611
 
19533
19612
  // watch for search watcher to trigger
19534
19613
  vue.nextTick(() => {
19535
- menu.value = false;
19614
+ menu.value = keepMenu;
19536
19615
  isPristine.value = true;
19537
19616
  });
19538
19617
  }
@@ -19546,9 +19625,6 @@
19546
19625
  function onFocusout(e) {
19547
19626
  listHasFocus.value = false;
19548
19627
  }
19549
- function onUpdateModelValue(v) {
19550
- if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
19551
- }
19552
19628
  vue.watch(isFocused, (val, oldVal) => {
19553
19629
  if (val || val === oldVal) return;
19554
19630
  selectionIndex.value = -1;
@@ -19571,13 +19647,14 @@
19571
19647
  }
19572
19648
  }
19573
19649
  });
19574
- vue.watch(menu, () => {
19575
- if (!props.hideSelected && menu.value && model.value.length) {
19650
+ vue.watch(menu, val => {
19651
+ if (!props.hideSelected && val && model.value.length && isPristine.value) {
19576
19652
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
19577
19653
  IN_BROWSER && window.requestAnimationFrame(() => {
19578
19654
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
19579
19655
  });
19580
19656
  }
19657
+ if (val) _searchLock.value = null;
19581
19658
  });
19582
19659
  vue.watch(items, (newVal, oldVal) => {
19583
19660
  if (menu.value) return;
@@ -19593,7 +19670,7 @@
19593
19670
  "ref": vTextFieldRef
19594
19671
  }, textFieldProps, {
19595
19672
  "modelValue": search.value,
19596
- "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
19673
+ "onUpdate:modelValue": $event => search.value = $event,
19597
19674
  "focused": isFocused.value,
19598
19675
  "onUpdate:focused": $event => isFocused.value = $event,
19599
19676
  "validationValue": model.externalValue,
@@ -19628,7 +19705,6 @@
19628
19705
  "maxHeight": 310,
19629
19706
  "openOnClick": false,
19630
19707
  "closeOnContentClick": false,
19631
- "transition": props.transition,
19632
19708
  "onAfterEnter": onAfterEnter,
19633
19709
  "onAfterLeave": onAfterLeave
19634
19710
  }, props.menuProps), {
@@ -24108,7 +24184,7 @@
24108
24184
  function isAllowedInRange(start, end) {
24109
24185
  const allowedDates = props.allowedDates;
24110
24186
  if (typeof allowedDates !== 'function') return true;
24111
- const days = adapter.getDiff(end, start, 'days');
24187
+ const days = 1 + adapter.getDiff(new Date(`${adapter.toISO(end)}T00:00:00Z`), new Date(`${adapter.toISO(start)}T00:00:00Z`), 'days');
24112
24188
  for (let i = 0; i < days; i++) {
24113
24189
  if (allowedDates(adapter.addDays(start, i))) return true;
24114
24190
  }
@@ -26611,7 +26687,7 @@
26611
26687
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
26612
26688
  const _inputText = vue.shallowRef(null);
26613
26689
  vue.watchEffect(() => {
26614
- if (isFocused.value && !controlsDisabled.value && Number(_inputText.value) === model.value) ; else if (model.value == null) {
26690
+ if (isFocused.value && !controlsDisabled.value && Number(_inputText.value?.replace(decimalSeparator.value, '.')) === model.value) ; else if (model.value == null) {
26615
26691
  _inputText.value = null;
26616
26692
  } else if (!isNaN(model.value)) {
26617
26693
  _inputText.value = correctPrecision(model.value);
@@ -26706,6 +26782,7 @@
26706
26782
  if (!new RegExp(`^-?\\d*${escapeForRegex(decimalSeparator.value)}?\\d*$`).test(potentialNewInputVal)) {
26707
26783
  e.preventDefault();
26708
26784
  inputElement.value = potentialNewNumber;
26785
+ vue.nextTick(() => inputText.value = potentialNewNumber);
26709
26786
  }
26710
26787
  if (props.precision == null) return;
26711
26788
 
@@ -26713,13 +26790,15 @@
26713
26790
  if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {
26714
26791
  e.preventDefault();
26715
26792
  inputElement.value = potentialNewNumber;
26793
+ vue.nextTick(() => inputText.value = potentialNewNumber);
26716
26794
  const cursorPosition = (selectionStart ?? 0) + e.data.length;
26717
26795
  inputElement.setSelectionRange(cursorPosition, cursorPosition);
26718
26796
  }
26719
26797
  // Ignore decimal separator when precision = 0
26720
- if (props.precision === 0 && potentialNewInputVal.includes(decimalSeparator.value)) {
26798
+ if (props.precision === 0 && potentialNewInputVal.endsWith(decimalSeparator.value)) {
26721
26799
  e.preventDefault();
26722
26800
  inputElement.value = potentialNewNumber;
26801
+ vue.nextTick(() => inputText.value = potentialNewNumber);
26723
26802
  }
26724
26803
  }
26725
26804
  async function onKeydown(e) {
@@ -27915,12 +27994,12 @@
27915
27994
  ariaLabel: t(props.loadingText),
27916
27995
  role: 'alert'
27917
27996
  };
27918
- return vue.createElementVNode(vue.Fragment, null, [isLoading ? vue.createElementVNode("div", vue.mergeProps({
27997
+ return isLoading ? vue.createElementVNode("div", vue.mergeProps({
27919
27998
  "class": ['v-skeleton-loader', {
27920
27999
  'v-skeleton-loader--boilerplate': props.boilerplate
27921
28000
  }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value],
27922
28001
  "style": [backgroundColorStyles.value, dimensionStyles.value]
27923
- }, loadingProps, attrs), [items.value]) : slots.default?.()]);
28002
+ }, loadingProps, attrs), [items.value]) : vue.createElementVNode(vue.Fragment, null, [slots.default?.()]);
27924
28003
  });
27925
28004
  return {};
27926
28005
  }
@@ -29785,6 +29864,10 @@
29785
29864
  const vFieldRef = vue.ref();
29786
29865
  const controlHeight = vue.shallowRef('');
29787
29866
  const textareaRef = vue.ref();
29867
+ const scrollbarWidth = vue.ref(0);
29868
+ const {
29869
+ platform
29870
+ } = useDisplay();
29788
29871
  const autocomplete = useAutocomplete(props);
29789
29872
  const isActive = vue.computed(() => props.persistentPlaceholder || isFocused.value || props.active);
29790
29873
  function onFocus() {
@@ -29829,6 +29912,18 @@
29829
29912
  if (!props.autoGrow) rows.value = Number(props.rows);
29830
29913
  });
29831
29914
  function calculateInputHeight() {
29915
+ vue.nextTick(() => {
29916
+ if (!textareaRef.value) return;
29917
+ if (platform.value.firefox) {
29918
+ scrollbarWidth.value = 12;
29919
+ return;
29920
+ }
29921
+ const {
29922
+ offsetWidth,
29923
+ clientWidth
29924
+ } = textareaRef.value;
29925
+ scrollbarWidth.value = Math.max(0, offsetWidth - clientWidth);
29926
+ });
29832
29927
  if (!props.autoGrow) return;
29833
29928
  vue.nextTick(() => {
29834
29929
  if (!sizerRef.value || !vFieldRef.value) return;
@@ -29889,7 +29984,9 @@
29889
29984
  'v-textarea--no-resize': props.noResize || props.autoGrow,
29890
29985
  'v-input--plain-underlined': isPlainOrUnderlined.value
29891
29986
  }, props.class],
29892
- "style": props.style
29987
+ "style": [{
29988
+ '--v-textarea-scroll-bar-width': convertToUnit(scrollbarWidth.value)
29989
+ }, props.style]
29893
29990
  }, rootAttrs, inputProps, {
29894
29991
  "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
29895
29992
  "focused": isFocused.value
@@ -34317,7 +34414,7 @@
34317
34414
  ...makeFocusProps(),
34318
34415
  ...makeVConfirmEditProps(),
34319
34416
  ...makeVTextFieldProps(),
34320
- ...omit(makeVColorPickerProps(), ['width'])
34417
+ ...omit(makeVColorPickerProps(), ['location', 'height', 'minHeight', 'maxHeight'])
34321
34418
  }, 'VColorInput');
34322
34419
  const VColorInput = genericComponent()({
34323
34420
  name: 'VColorInput',
@@ -34356,7 +34453,7 @@
34356
34453
  }
34357
34454
  useRender(() => {
34358
34455
  const confirmEditProps = VConfirmEdit.filterProps(props);
34359
- const colorPickerProps = VColorPicker.filterProps(omit(props, ['active', 'color']));
34456
+ const colorPickerProps = VColorPicker.filterProps(omit(props, ['active', 'bgColor', 'color', 'rounded', 'maxWidth', 'minWidth', 'width']));
34360
34457
  const textFieldProps = VTextField.filterProps(props);
34361
34458
  const slotWithPip = props.hidePip ? undefined : {
34362
34459
  [props.pipLocation]: arg => vue.createElementVNode(vue.Fragment, null, [vue.createVNode(VAvatar, {
@@ -34574,7 +34671,7 @@
34574
34671
  ...omit(makeVDatePickerProps({
34575
34672
  hideHeader: true,
34576
34673
  showAdjacentMonths: true
34577
- }), ['active', 'location', 'rounded'])
34674
+ }), ['active', 'location', 'rounded', 'height', 'minHeight', 'maxHeight'])
34578
34675
  }, 'VDateInput');
34579
34676
  const VDateInput = genericComponent()({
34580
34677
  name: 'VDateInput',
@@ -34605,6 +34702,15 @@
34605
34702
  const {
34606
34703
  mobile
34607
34704
  } = useDisplay(props);
34705
+ const clamp = date => {
34706
+ if (props.max && adapter.isAfter(date, props.max)) {
34707
+ return props.max;
34708
+ }
34709
+ if (props.min && adapter.isBefore(date, props.min)) {
34710
+ return props.min;
34711
+ }
34712
+ return date;
34713
+ };
34608
34714
  const emptyModelValue = () => props.multiple ? [] : null;
34609
34715
  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);
34610
34716
  const menu = useProxiedModel(props, 'menu');
@@ -34655,7 +34761,7 @@
34655
34761
  if (!menu.value || !isFocused.value) {
34656
34762
  menu.value = true;
34657
34763
  }
34658
- if (props.updateOn.includes('enter')) {
34764
+ if (props.updateOn.includes('enter') && !props.readonly) {
34659
34765
  onUserInput(e.target);
34660
34766
  }
34661
34767
  }
@@ -34682,7 +34788,7 @@
34682
34788
  model.value = emptyModelValue();
34683
34789
  }
34684
34790
  function onBlur(e) {
34685
- if (props.updateOn.includes('blur')) {
34791
+ if (props.updateOn.includes('blur') && !props.readonly) {
34686
34792
  onUserInput(e.target);
34687
34793
  }
34688
34794
 
@@ -34700,23 +34806,23 @@
34700
34806
  model.value = emptyModelValue();
34701
34807
  } else if (!props.multiple) {
34702
34808
  if (isValid(value)) {
34703
- model.value = parseDate(value);
34809
+ model.value = clamp(parseDate(value));
34704
34810
  }
34705
34811
  } else {
34706
34812
  const parts = value.trim().split(/\D+-\D+|[^\d\-/.]+/);
34707
34813
  if (parts.every(isValid)) {
34708
34814
  if (props.multiple === 'range') {
34709
- const [start, stop] = parts.map(parseDate).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
34815
+ const [start, stop] = parts.map(parseDate).map(clamp).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
34710
34816
  model.value = createDateRange(adapter, start, stop);
34711
34817
  } else {
34712
- model.value = parts.map(parseDate);
34818
+ model.value = parts.map(parseDate).map(clamp);
34713
34819
  }
34714
34820
  }
34715
34821
  }
34716
34822
  }
34717
34823
  useRender(() => {
34718
34824
  const confirmEditProps = VConfirmEdit.filterProps(props);
34719
- const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'location', 'rounded']));
34825
+ const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'bgColor', 'color', 'location', 'rounded', 'maxWidth', 'minWidth', 'width']));
34720
34826
  const datePickerSlots = pick(slots, ['title', 'header', 'day', 'month', 'year']);
34721
34827
  const textFieldProps = VTextField.filterProps(omit(props, ['placeholder']));
34722
34828
  return vue.createVNode(VTextField, vue.mergeProps({
@@ -35161,7 +35267,7 @@
35161
35267
  // Always display masked value in input when mask is applied
35162
35268
  val => props.mask ? mask.mask(mask.unmask(val)) : val, val => {
35163
35269
  if (props.mask) {
35164
- const valueWithoutDelimiters = removeMaskDelimiters(val);
35270
+ const valueWithoutDelimiters = val ? removeMaskDelimiters(val) : '';
35165
35271
 
35166
35272
  // E.g. mask is #-# and the input value is '2-23'
35167
35273
  // model-value should be enforced to '2-2'
@@ -37907,7 +38013,7 @@
37907
38013
  };
37908
38014
  });
37909
38015
  }
37910
- const version$1 = "3.10.5";
38016
+ const version$1 = "3.10.6";
37911
38017
  createVuetify$1.version = version$1;
37912
38018
 
37913
38019
  // Vue's inject() can only be used in setup
@@ -38205,7 +38311,7 @@
38205
38311
 
38206
38312
  /* eslint-disable local-rules/sort-imports */
38207
38313
 
38208
- const version = "3.10.5";
38314
+ const version = "3.10.6";
38209
38315
 
38210
38316
  /* eslint-disable local-rules/sort-imports */
38211
38317