vuetify 3.10.5 → 3.10.7

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 (94) hide show
  1. package/README.md +0 -6
  2. package/dist/json/attributes.json +3488 -3512
  3. package/dist/json/importMap-labs.json +20 -20
  4. package/dist/json/importMap.json +176 -176
  5. package/dist/json/tags.json +3 -9
  6. package/dist/json/web-types.json +6467 -6520
  7. package/dist/vuetify-labs.cjs +190 -82
  8. package/dist/vuetify-labs.css +4945 -4895
  9. package/dist/vuetify-labs.d.ts +117 -172
  10. package/dist/vuetify-labs.esm.js +190 -82
  11. package/dist/vuetify-labs.esm.js.map +1 -1
  12. package/dist/vuetify-labs.js +190 -82
  13. package/dist/vuetify-labs.min.css +2 -2
  14. package/dist/vuetify.cjs +171 -72
  15. package/dist/vuetify.cjs.map +1 -1
  16. package/dist/vuetify.css +3926 -3898
  17. package/dist/vuetify.d.ts +117 -137
  18. package/dist/vuetify.esm.js +171 -72
  19. package/dist/vuetify.esm.js.map +1 -1
  20. package/dist/vuetify.js +171 -72
  21. package/dist/vuetify.js.map +1 -1
  22. package/dist/vuetify.min.css +2 -2
  23. package/dist/vuetify.min.js +118 -107
  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 +15 -12
  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 +29 -30
  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/VFileInput/VFileInput.js +3 -2
  39. package/lib/components/VFileInput/VFileInput.js.map +1 -1
  40. package/lib/components/VList/VListItem.css +14 -12
  41. package/lib/components/VList/VListItem.js +4 -2
  42. package/lib/components/VList/VListItem.js.map +1 -1
  43. package/lib/components/VList/VListItem.sass +20 -18
  44. package/lib/components/VMenu/VMenu.js +22 -4
  45. package/lib/components/VMenu/VMenu.js.map +1 -1
  46. package/lib/components/VNumberInput/VNumberInput.css +8 -0
  47. package/lib/components/VNumberInput/VNumberInput.js +5 -2
  48. package/lib/components/VNumberInput/VNumberInput.js.map +1 -1
  49. package/lib/components/VNumberInput/VNumberInput.sass +10 -4
  50. package/lib/components/VSelect/VSelect.js +2 -1
  51. package/lib/components/VSelect/VSelect.js.map +1 -1
  52. package/lib/components/VSkeletonLoader/VSkeletonLoader.css +17 -0
  53. package/lib/components/VSkeletonLoader/VSkeletonLoader.js +3 -3
  54. package/lib/components/VSkeletonLoader/VSkeletonLoader.js.map +1 -1
  55. package/lib/components/VSkeletonLoader/VSkeletonLoader.sass +7 -0
  56. package/lib/components/VSlideGroup/VSlideGroup.d.ts +25 -0
  57. package/lib/components/VSlideGroup/VSlideGroup.js +5 -1
  58. package/lib/components/VSlideGroup/VSlideGroup.js.map +1 -1
  59. package/lib/components/VTabs/VTabs.d.ts +25 -0
  60. package/lib/components/VTextField/VTextField.js +3 -5
  61. package/lib/components/VTextField/VTextField.js.map +1 -1
  62. package/lib/components/VTextarea/VTextarea.css +2 -2
  63. package/lib/components/VTextarea/VTextarea.d.ts +3 -3
  64. package/lib/components/VTextarea/VTextarea.js +23 -3
  65. package/lib/components/VTextarea/VTextarea.js.map +1 -1
  66. package/lib/components/VTextarea/VTextarea.sass +4 -2
  67. package/lib/components/VWindow/VWindow.js +39 -3
  68. package/lib/components/VWindow/VWindow.js.map +1 -1
  69. package/lib/composables/date/date.js +1 -1
  70. package/lib/composables/date/date.js.map +1 -1
  71. package/lib/composables/group.js +1 -1
  72. package/lib/composables/group.js.map +1 -1
  73. package/lib/composables/nested/nested.js +12 -2
  74. package/lib/composables/nested/nested.js.map +1 -1
  75. package/lib/composables/virtual.js +2 -2
  76. package/lib/composables/virtual.js.map +1 -1
  77. package/lib/entry-bundler.js +1 -1
  78. package/lib/framework.d.ts +60 -60
  79. package/lib/framework.js +1 -1
  80. package/lib/labs/VColorInput/VColorInput.d.ts +0 -40
  81. package/lib/labs/VColorInput/VColorInput.js +2 -2
  82. package/lib/labs/VColorInput/VColorInput.js.map +1 -1
  83. package/lib/labs/VDateInput/VDateInput.d.ts +0 -30
  84. package/lib/labs/VDateInput/VDateInput.js +16 -7
  85. package/lib/labs/VDateInput/VDateInput.js.map +1 -1
  86. package/lib/labs/VIconBtn/VIconBtn.css +22 -0
  87. package/lib/labs/VIconBtn/VIconBtn.scss +32 -0
  88. package/lib/labs/VMaskInput/VMaskInput.js +1 -1
  89. package/lib/labs/VMaskInput/VMaskInput.js.map +1 -1
  90. package/lib/labs/rules/rules.js +1 -1
  91. package/lib/labs/rules/rules.js.map +1 -1
  92. package/lib/util/helpers.js +4 -2
  93. package/lib/util/helpers.js.map +1 -1
  94. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.10.5
2
+ * Vuetify v3.10.7
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,
@@ -12751,10 +12786,11 @@
12751
12786
  props: {
12752
12787
  class: fieldClass,
12753
12788
  ...slotProps
12754
- }
12789
+ },
12790
+ controlRef
12755
12791
  } = _ref3;
12756
12792
  const inputNode = vue.withDirectives(vue.createElementVNode("input", vue.mergeProps({
12757
- "ref": inputRef,
12793
+ "ref": val => inputRef.value = controlRef.value = val,
12758
12794
  "value": model.value,
12759
12795
  "onInput": onInput,
12760
12796
  "autofocus": props.autofocus,
@@ -12910,7 +12946,7 @@
12910
12946
  const start = performance.now();
12911
12947
  offsets[0] = 0;
12912
12948
  const length = items.value.length;
12913
- for (let i = 1; i <= length - 1; i++) {
12949
+ for (let i = 1; i <= length; i++) {
12914
12950
  offsets[i] = (offsets[i - 1] || 0) + getSize(i - 1);
12915
12951
  }
12916
12952
  updateTime.value = Math.max(updateTime.value, performance.now() - start);
@@ -12945,7 +12981,7 @@
12945
12981
  }
12946
12982
  }
12947
12983
  function calculateOffset(index) {
12948
- index = clamp(index, 0, items.value.length - 1);
12984
+ index = clamp(index, 0, items.value.length);
12949
12985
  const whole = Math.floor(index);
12950
12986
  const fraction = index % 1;
12951
12987
  const next = whole + 1;
@@ -13678,7 +13714,8 @@
13678
13714
  "key": item.value,
13679
13715
  "modelValue": isSelected,
13680
13716
  "ripple": false,
13681
- "tabindex": "-1"
13717
+ "tabindex": "-1",
13718
+ "onClick": event => event.preventDefault()
13682
13719
  }, null) : undefined, camelizedProps.prependAvatar && vue.createVNode(VAvatar, {
13683
13720
  "image": camelizedProps.prependAvatar
13684
13721
  }, null), camelizedProps.prependIcon && vue.createVNode(VIcon, {
@@ -13950,10 +13987,7 @@
13950
13987
  ...omit(makeVTextFieldProps({
13951
13988
  modelValue: null,
13952
13989
  role: 'combobox'
13953
- }), ['validationValue', 'dirty', 'appendInnerIcon']),
13954
- ...makeTransitionProps({
13955
- transition: false
13956
- })
13990
+ }), ['validationValue', 'dirty', 'appendInnerIcon'])
13957
13991
  }, 'VAutocomplete');
13958
13992
  const VAutocomplete = genericComponent()({
13959
13993
  name: 'VAutocomplete',
@@ -13978,6 +14012,7 @@
13978
14012
  const vMenuRef = vue.ref();
13979
14013
  const vVirtualScrollRef = vue.ref();
13980
14014
  const selectionIndex = vue.shallowRef(-1);
14015
+ const _searchLock = vue.shallowRef(null);
13981
14016
  const {
13982
14017
  items,
13983
14018
  transformIn,
@@ -13999,9 +14034,9 @@
13999
14034
  const {
14000
14035
  filteredItems,
14001
14036
  getMatches
14002
- } = useFilter(props, items, () => isPristine.value ? '' : search.value);
14037
+ } = useFilter(props, items, () => _searchLock.value ?? (isPristine.value ? '' : search.value));
14003
14038
  const displayItems = vue.computed(() => {
14004
- if (props.hideSelected) {
14039
+ if (props.hideSelected && _searchLock.value === null) {
14005
14040
  return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
14006
14041
  }
14007
14042
  return filteredItems.value;
@@ -14132,6 +14167,7 @@
14132
14167
  isPristine.value = true;
14133
14168
  vTextFieldRef.value?.focus();
14134
14169
  }
14170
+ _searchLock.value = null;
14135
14171
  }
14136
14172
  function onFocusin(e) {
14137
14173
  isFocused.value = true;
@@ -14167,6 +14203,7 @@
14167
14203
  } else {
14168
14204
  const add = set !== false;
14169
14205
  model.value = add ? [item] : [];
14206
+ _searchLock.value = isPristine.value ? '' : search.value ?? '';
14170
14207
  search.value = add && !hasSelectionSlot.value ? item.title : '';
14171
14208
 
14172
14209
  // watch for search watcher to trigger
@@ -14186,6 +14223,9 @@
14186
14223
  } else {
14187
14224
  if (!props.multiple && search.value == null) model.value = [];
14188
14225
  menu.value = false;
14226
+ if (!isPristine.value && search.value) {
14227
+ _searchLock.value = search.value;
14228
+ }
14189
14229
  search.value = '';
14190
14230
  selectionIndex.value = -1;
14191
14231
  }
@@ -14195,13 +14235,14 @@
14195
14235
  if (val) menu.value = true;
14196
14236
  isPristine.value = !val;
14197
14237
  });
14198
- vue.watch(menu, () => {
14199
- if (!props.hideSelected && menu.value && model.value.length) {
14238
+ vue.watch(menu, val => {
14239
+ if (!props.hideSelected && val && model.value.length && isPristine.value) {
14200
14240
  const index = displayItems.value.findIndex(item => model.value.some(s => item.value === s.value));
14201
14241
  IN_BROWSER && window.requestAnimationFrame(() => {
14202
14242
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
14203
14243
  });
14204
14244
  }
14245
+ if (val) _searchLock.value = null;
14205
14246
  });
14206
14247
  vue.watch(items, (newVal, oldVal) => {
14207
14248
  if (menu.value) return;
@@ -14252,7 +14293,6 @@
14252
14293
  "maxHeight": 310,
14253
14294
  "openOnClick": false,
14254
14295
  "closeOnContentClick": false,
14255
- "transition": props.transition,
14256
14296
  "onAfterEnter": onAfterEnter,
14257
14297
  "onAfterLeave": onAfterLeave
14258
14298
  }, props.menuProps), {
@@ -14322,7 +14362,8 @@
14322
14362
  "key": item.value,
14323
14363
  "modelValue": isSelected,
14324
14364
  "ripple": false,
14325
- "tabindex": "-1"
14365
+ "tabindex": "-1",
14366
+ "onClick": event => event.preventDefault()
14326
14367
  }, null) : undefined, item.props.prependAvatar && vue.createVNode(VAvatar, {
14327
14368
  "image": item.props.prependAvatar
14328
14369
  }, null), item.props.prependIcon && vue.createVNode(VIcon, {
@@ -15680,7 +15721,19 @@
15680
15721
  const activeIndex = vue.computed(() => {
15681
15722
  return group.items.value.findIndex(item => group.selected.value.includes(item.id));
15682
15723
  });
15724
+
15725
+ // Fix for https://github.com/vuetifyjs/vuetify/issues/18447
15683
15726
  vue.watch(activeIndex, (newVal, oldVal) => {
15727
+ let scrollableParent;
15728
+ const savedScrollPosition = {
15729
+ left: 0,
15730
+ top: 0
15731
+ };
15732
+ if (IN_BROWSER && oldVal >= 0) {
15733
+ scrollableParent = getScrollParent(rootRef.value);
15734
+ savedScrollPosition.left = scrollableParent?.scrollLeft;
15735
+ savedScrollPosition.top = scrollableParent?.scrollTop;
15736
+ }
15684
15737
  const itemsLength = group.items.value.length;
15685
15738
  const lastIndex = itemsLength - 1;
15686
15739
  if (itemsLength <= 2) {
@@ -15692,7 +15745,30 @@
15692
15745
  } else {
15693
15746
  isReversed.value = newVal < oldVal;
15694
15747
  }
15695
- });
15748
+ vue.nextTick(() => {
15749
+ if (!IN_BROWSER || !scrollableParent) return;
15750
+ const currentScrollY = scrollableParent.scrollTop;
15751
+ if (currentScrollY !== savedScrollPosition.top) {
15752
+ scrollableParent.scrollTo({
15753
+ ...savedScrollPosition,
15754
+ behavior: 'instant'
15755
+ });
15756
+ }
15757
+ requestAnimationFrame(() => {
15758
+ if (!scrollableParent) return;
15759
+ const rafScrollY = scrollableParent.scrollTop;
15760
+ if (rafScrollY !== savedScrollPosition.top) {
15761
+ scrollableParent.scrollTo({
15762
+ ...savedScrollPosition,
15763
+ behavior: 'instant'
15764
+ });
15765
+ }
15766
+ });
15767
+ });
15768
+ }, {
15769
+ flush: 'sync'
15770
+ }); // Run synchronously before DOM updates
15771
+
15696
15772
  vue.provide(VWindowSymbol, {
15697
15773
  transition,
15698
15774
  isReversed,
@@ -18597,7 +18673,7 @@
18597
18673
  };
18598
18674
  }
18599
18675
  function createDateRange(adapter, start, stop) {
18600
- const diff = adapter.getDiff(adapter.endOfDay(stop ?? start), adapter.startOfDay(start), 'days');
18676
+ const diff = adapter.getDiff(new Date(`${adapter.toISO(stop ?? start)}T00:00:00Z`), new Date(`${adapter.toISO(start)}T00:00:00Z`), 'days');
18601
18677
  const datesInRange = [start];
18602
18678
  for (let i = 1; i < diff; i++) {
18603
18679
  const nextDate = adapter.addDays(start, i);
@@ -19280,10 +19356,7 @@
19280
19356
  ...omit(makeVTextFieldProps({
19281
19357
  modelValue: null,
19282
19358
  role: 'combobox'
19283
- }), ['validationValue', 'dirty', 'appendInnerIcon']),
19284
- ...makeTransitionProps({
19285
- transition: false
19286
- })
19359
+ }), ['validationValue', 'dirty', 'appendInnerIcon'])
19287
19360
  }, 'VCombobox');
19288
19361
  const VCombobox = genericComponent()({
19289
19362
  name: 'VCombobox',
@@ -19327,13 +19400,16 @@
19327
19400
  const hasChips = vue.computed(() => !!(props.chips || slots.chip));
19328
19401
  const hasSelectionSlot = vue.computed(() => hasChips.value || !!slots.selection);
19329
19402
  const _search = vue.shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
19403
+ const _searchLock = vue.shallowRef(null);
19330
19404
  const search = vue.computed({
19331
19405
  get: () => {
19332
19406
  return _search.value;
19333
19407
  },
19334
19408
  set: async val => {
19335
19409
  _search.value = val ?? '';
19336
- if (!props.multiple && !hasSelectionSlot.value) {
19410
+ if (val === null || val === '' && !props.multiple && !hasSelectionSlot.value) {
19411
+ model.value = [];
19412
+ } else if (!props.multiple && !hasSelectionSlot.value) {
19337
19413
  model.value = [transformItem$3(props, val)];
19338
19414
  vue.nextTick(() => vVirtualScrollRef.value?.scrollToIndex(0));
19339
19415
  }
@@ -19361,9 +19437,9 @@
19361
19437
  const {
19362
19438
  filteredItems,
19363
19439
  getMatches
19364
- } = useFilter(props, items, () => props.alwaysFilter || !isPristine.value ? search.value : '');
19440
+ } = useFilter(props, items, () => _searchLock.value ?? (props.alwaysFilter || !isPristine.value ? search.value : ''));
19365
19441
  const displayItems = vue.computed(() => {
19366
- if (props.hideSelected) {
19442
+ if (props.hideSelected && _searchLock.value === null) {
19367
19443
  return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
19368
19444
  }
19369
19445
  return filteredItems.value;
@@ -19444,22 +19520,19 @@
19444
19520
  if (['Escape'].includes(e.key)) {
19445
19521
  menu.value = false;
19446
19522
  }
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;
19523
+ if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
19524
+ let {
19525
+ value
19526
+ } = _ref2;
19527
+ return value === displayItems.value[0].value;
19528
+ })) {
19529
+ select(filteredItems.value[0]);
19457
19530
  }
19458
19531
  if (e.key === 'ArrowDown' && highlightFirst.value) {
19459
19532
  listRef.value?.focus('next');
19460
19533
  }
19461
19534
  if (e.key === 'Enter' && search.value) {
19462
- select(transformItem$3(props, search.value));
19535
+ select(transformItem$3(props, search.value), true, true);
19463
19536
  if (hasSelectionSlot.value) _search.value = '';
19464
19537
  }
19465
19538
  if (['Backspace', 'Delete'].includes(e.key)) {
@@ -19504,13 +19577,15 @@
19504
19577
  }
19505
19578
  function onAfterLeave() {
19506
19579
  if (isFocused.value) {
19507
- isPristine.value = true;
19508
19580
  vTextFieldRef.value?.focus();
19509
19581
  }
19582
+ isPristine.value = true;
19583
+ _searchLock.value = null;
19510
19584
  }
19511
19585
  /** @param set - null means toggle */
19512
19586
  function select(item) {
19513
19587
  let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19588
+ let keepMenu = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
19514
19589
  if (!item || item.props.disabled) return;
19515
19590
  if (props.multiple) {
19516
19591
  const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value));
@@ -19528,11 +19603,14 @@
19528
19603
  } else {
19529
19604
  const add = set !== false;
19530
19605
  model.value = add ? [item] : [];
19606
+ if ((!isPristine.value || props.alwaysFilter) && _search.value) {
19607
+ _searchLock.value = _search.value;
19608
+ }
19531
19609
  _search.value = add && !hasSelectionSlot.value ? item.title : '';
19532
19610
 
19533
19611
  // watch for search watcher to trigger
19534
19612
  vue.nextTick(() => {
19535
- menu.value = false;
19613
+ menu.value = keepMenu;
19536
19614
  isPristine.value = true;
19537
19615
  });
19538
19616
  }
@@ -19546,9 +19624,6 @@
19546
19624
  function onFocusout(e) {
19547
19625
  listHasFocus.value = false;
19548
19626
  }
19549
- function onUpdateModelValue(v) {
19550
- if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
19551
- }
19552
19627
  vue.watch(isFocused, (val, oldVal) => {
19553
19628
  if (val || val === oldVal) return;
19554
19629
  selectionIndex.value = -1;
@@ -19571,13 +19646,14 @@
19571
19646
  }
19572
19647
  }
19573
19648
  });
19574
- vue.watch(menu, () => {
19575
- if (!props.hideSelected && menu.value && model.value.length) {
19649
+ vue.watch(menu, val => {
19650
+ if (!props.hideSelected && val && model.value.length && isPristine.value) {
19576
19651
  const index = displayItems.value.findIndex(item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value)));
19577
19652
  IN_BROWSER && window.requestAnimationFrame(() => {
19578
19653
  index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
19579
19654
  });
19580
19655
  }
19656
+ if (val) _searchLock.value = null;
19581
19657
  });
19582
19658
  vue.watch(items, (newVal, oldVal) => {
19583
19659
  if (menu.value) return;
@@ -19593,7 +19669,7 @@
19593
19669
  "ref": vTextFieldRef
19594
19670
  }, textFieldProps, {
19595
19671
  "modelValue": search.value,
19596
- "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
19672
+ "onUpdate:modelValue": $event => search.value = $event,
19597
19673
  "focused": isFocused.value,
19598
19674
  "onUpdate:focused": $event => isFocused.value = $event,
19599
19675
  "validationValue": model.externalValue,
@@ -19628,7 +19704,6 @@
19628
19704
  "maxHeight": 310,
19629
19705
  "openOnClick": false,
19630
19706
  "closeOnContentClick": false,
19631
- "transition": props.transition,
19632
19707
  "onAfterEnter": onAfterEnter,
19633
19708
  "onAfterLeave": onAfterLeave
19634
19709
  }, props.menuProps), {
@@ -19698,7 +19773,8 @@
19698
19773
  "key": item.value,
19699
19774
  "modelValue": isSelected,
19700
19775
  "ripple": false,
19701
- "tabindex": "-1"
19776
+ "tabindex": "-1",
19777
+ "onClick": event => event.preventDefault()
19702
19778
  }, null) : undefined, item.props.prependAvatar && vue.createVNode(VAvatar, {
19703
19779
  "image": item.props.prependAvatar
19704
19780
  }, null), item.props.prependIcon && vue.createVNode(VIcon, {
@@ -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
  }
@@ -25131,10 +25207,11 @@
25131
25207
  props: {
25132
25208
  class: fieldClass,
25133
25209
  ...slotProps
25134
- }
25210
+ },
25211
+ controlRef
25135
25212
  } = _ref4;
25136
25213
  return vue.createElementVNode(vue.Fragment, null, [vue.createElementVNode("input", vue.mergeProps({
25137
- "ref": inputRef,
25214
+ "ref": val => inputRef.value = controlRef.value = val,
25138
25215
  "type": "file",
25139
25216
  "accept": inputAccept,
25140
25217
  "readonly": isReadonly.value,
@@ -26611,7 +26688,7 @@
26611
26688
  const model = useProxiedModel(props, 'modelValue', null, val => val ?? null, val => val == null ? val ?? null : clamp(Number(val), props.min, props.max));
26612
26689
  const _inputText = vue.shallowRef(null);
26613
26690
  vue.watchEffect(() => {
26614
- if (isFocused.value && !controlsDisabled.value && Number(_inputText.value) === model.value) ; else if (model.value == null) {
26691
+ if (isFocused.value && !controlsDisabled.value && Number(_inputText.value?.replace(decimalSeparator.value, '.')) === model.value) ; else if (model.value == null) {
26615
26692
  _inputText.value = null;
26616
26693
  } else if (!isNaN(model.value)) {
26617
26694
  _inputText.value = correctPrecision(model.value);
@@ -26706,6 +26783,7 @@
26706
26783
  if (!new RegExp(`^-?\\d*${escapeForRegex(decimalSeparator.value)}?\\d*$`).test(potentialNewInputVal)) {
26707
26784
  e.preventDefault();
26708
26785
  inputElement.value = potentialNewNumber;
26786
+ vue.nextTick(() => inputText.value = potentialNewNumber);
26709
26787
  }
26710
26788
  if (props.precision == null) return;
26711
26789
 
@@ -26713,13 +26791,15 @@
26713
26791
  if (potentialNewInputVal.split(decimalSeparator.value)[1]?.length > props.precision) {
26714
26792
  e.preventDefault();
26715
26793
  inputElement.value = potentialNewNumber;
26794
+ vue.nextTick(() => inputText.value = potentialNewNumber);
26716
26795
  const cursorPosition = (selectionStart ?? 0) + e.data.length;
26717
26796
  inputElement.setSelectionRange(cursorPosition, cursorPosition);
26718
26797
  }
26719
26798
  // Ignore decimal separator when precision = 0
26720
- if (props.precision === 0 && potentialNewInputVal.includes(decimalSeparator.value)) {
26799
+ if (props.precision === 0 && potentialNewInputVal.endsWith(decimalSeparator.value)) {
26721
26800
  e.preventDefault();
26722
26801
  inputElement.value = potentialNewNumber;
26802
+ vue.nextTick(() => inputText.value = potentialNewNumber);
26723
26803
  }
26724
26804
  }
26725
26805
  async function onKeydown(e) {
@@ -27915,12 +27995,12 @@
27915
27995
  ariaLabel: t(props.loadingText),
27916
27996
  role: 'alert'
27917
27997
  };
27918
- return vue.createElementVNode(vue.Fragment, null, [isLoading ? vue.createElementVNode("div", vue.mergeProps({
27998
+ return isLoading ? vue.createElementVNode("div", vue.mergeProps({
27919
27999
  "class": ['v-skeleton-loader', {
27920
28000
  'v-skeleton-loader--boilerplate': props.boilerplate
27921
28001
  }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value],
27922
28002
  "style": [backgroundColorStyles.value, dimensionStyles.value]
27923
- }, loadingProps, attrs), [items.value]) : slots.default?.()]);
28003
+ }, loadingProps, attrs), [items.value]) : vue.createElementVNode(vue.Fragment, null, [slots.default?.()]);
27924
28004
  });
27925
28005
  return {};
27926
28006
  }
@@ -29785,6 +29865,10 @@
29785
29865
  const vFieldRef = vue.ref();
29786
29866
  const controlHeight = vue.shallowRef('');
29787
29867
  const textareaRef = vue.ref();
29868
+ const scrollbarWidth = vue.ref(0);
29869
+ const {
29870
+ platform
29871
+ } = useDisplay();
29788
29872
  const autocomplete = useAutocomplete(props);
29789
29873
  const isActive = vue.computed(() => props.persistentPlaceholder || isFocused.value || props.active);
29790
29874
  function onFocus() {
@@ -29829,6 +29913,18 @@
29829
29913
  if (!props.autoGrow) rows.value = Number(props.rows);
29830
29914
  });
29831
29915
  function calculateInputHeight() {
29916
+ vue.nextTick(() => {
29917
+ if (!textareaRef.value) return;
29918
+ if (platform.value.firefox) {
29919
+ scrollbarWidth.value = 12;
29920
+ return;
29921
+ }
29922
+ const {
29923
+ offsetWidth,
29924
+ clientWidth
29925
+ } = textareaRef.value;
29926
+ scrollbarWidth.value = Math.max(0, offsetWidth - clientWidth);
29927
+ });
29832
29928
  if (!props.autoGrow) return;
29833
29929
  vue.nextTick(() => {
29834
29930
  if (!sizerRef.value || !vFieldRef.value) return;
@@ -29889,7 +29985,9 @@
29889
29985
  'v-textarea--no-resize': props.noResize || props.autoGrow,
29890
29986
  'v-input--plain-underlined': isPlainOrUnderlined.value
29891
29987
  }, props.class],
29892
- "style": props.style
29988
+ "style": [{
29989
+ '--v-textarea-scroll-bar-width': convertToUnit(scrollbarWidth.value)
29990
+ }, props.style]
29893
29991
  }, rootAttrs, inputProps, {
29894
29992
  "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
29895
29993
  "focused": isFocused.value
@@ -29929,12 +30027,13 @@
29929
30027
  props: {
29930
30028
  class: fieldClass,
29931
30029
  ...slotProps
29932
- }
30030
+ },
30031
+ controlRef
29933
30032
  } = _ref3;
29934
30033
  return vue.createElementVNode(vue.Fragment, null, [props.prefix && vue.createElementVNode("span", {
29935
30034
  "class": "v-text-field__prefix"
29936
30035
  }, [props.prefix]), vue.withDirectives(vue.createElementVNode("textarea", vue.mergeProps({
29937
- "ref": textareaRef,
30036
+ "ref": val => textareaRef.value = controlRef.value = val,
29938
30037
  "class": fieldClass,
29939
30038
  "value": model.value,
29940
30039
  "onInput": onInput,
@@ -34317,7 +34416,7 @@
34317
34416
  ...makeFocusProps(),
34318
34417
  ...makeVConfirmEditProps(),
34319
34418
  ...makeVTextFieldProps(),
34320
- ...omit(makeVColorPickerProps(), ['width'])
34419
+ ...omit(makeVColorPickerProps(), ['location', 'height', 'minHeight', 'maxHeight'])
34321
34420
  }, 'VColorInput');
34322
34421
  const VColorInput = genericComponent()({
34323
34422
  name: 'VColorInput',
@@ -34356,7 +34455,7 @@
34356
34455
  }
34357
34456
  useRender(() => {
34358
34457
  const confirmEditProps = VConfirmEdit.filterProps(props);
34359
- const colorPickerProps = VColorPicker.filterProps(omit(props, ['active', 'color']));
34458
+ const colorPickerProps = VColorPicker.filterProps(omit(props, ['active', 'bgColor', 'color', 'rounded', 'maxWidth', 'minWidth', 'width']));
34360
34459
  const textFieldProps = VTextField.filterProps(props);
34361
34460
  const slotWithPip = props.hidePip ? undefined : {
34362
34461
  [props.pipLocation]: arg => vue.createElementVNode(vue.Fragment, null, [vue.createVNode(VAvatar, {
@@ -34574,7 +34673,7 @@
34574
34673
  ...omit(makeVDatePickerProps({
34575
34674
  hideHeader: true,
34576
34675
  showAdjacentMonths: true
34577
- }), ['active', 'location', 'rounded'])
34676
+ }), ['active', 'location', 'rounded', 'height', 'minHeight', 'maxHeight'])
34578
34677
  }, 'VDateInput');
34579
34678
  const VDateInput = genericComponent()({
34580
34679
  name: 'VDateInput',
@@ -34605,6 +34704,15 @@
34605
34704
  const {
34606
34705
  mobile
34607
34706
  } = useDisplay(props);
34707
+ const clamp = date => {
34708
+ if (props.max && adapter.isAfter(date, props.max)) {
34709
+ return props.max;
34710
+ }
34711
+ if (props.min && adapter.isBefore(date, props.min)) {
34712
+ return props.min;
34713
+ }
34714
+ return date;
34715
+ };
34608
34716
  const emptyModelValue = () => props.multiple ? [] : null;
34609
34717
  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
34718
  const menu = useProxiedModel(props, 'menu');
@@ -34655,7 +34763,7 @@
34655
34763
  if (!menu.value || !isFocused.value) {
34656
34764
  menu.value = true;
34657
34765
  }
34658
- if (props.updateOn.includes('enter')) {
34766
+ if (props.updateOn.includes('enter') && !props.readonly) {
34659
34767
  onUserInput(e.target);
34660
34768
  }
34661
34769
  }
@@ -34682,7 +34790,7 @@
34682
34790
  model.value = emptyModelValue();
34683
34791
  }
34684
34792
  function onBlur(e) {
34685
- if (props.updateOn.includes('blur')) {
34793
+ if (props.updateOn.includes('blur') && !props.readonly) {
34686
34794
  onUserInput(e.target);
34687
34795
  }
34688
34796
 
@@ -34700,23 +34808,23 @@
34700
34808
  model.value = emptyModelValue();
34701
34809
  } else if (!props.multiple) {
34702
34810
  if (isValid(value)) {
34703
- model.value = parseDate(value);
34811
+ model.value = clamp(parseDate(value));
34704
34812
  }
34705
34813
  } else {
34706
34814
  const parts = value.trim().split(/\D+-\D+|[^\d\-/.]+/);
34707
34815
  if (parts.every(isValid)) {
34708
34816
  if (props.multiple === 'range') {
34709
- const [start, stop] = parts.map(parseDate).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
34817
+ const [start, stop] = parts.map(parseDate).map(clamp).toSorted((a, b) => adapter.isAfter(a, b) ? 1 : -1);
34710
34818
  model.value = createDateRange(adapter, start, stop);
34711
34819
  } else {
34712
- model.value = parts.map(parseDate);
34820
+ model.value = parts.map(parseDate).map(clamp);
34713
34821
  }
34714
34822
  }
34715
34823
  }
34716
34824
  }
34717
34825
  useRender(() => {
34718
34826
  const confirmEditProps = VConfirmEdit.filterProps(props);
34719
- const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'location', 'rounded']));
34827
+ const datePickerProps = VDatePicker.filterProps(omit(props, ['active', 'bgColor', 'color', 'location', 'rounded', 'maxWidth', 'minWidth', 'width']));
34720
34828
  const datePickerSlots = pick(slots, ['title', 'header', 'day', 'month', 'year']);
34721
34829
  const textFieldProps = VTextField.filterProps(omit(props, ['placeholder']));
34722
34830
  return vue.createVNode(VTextField, vue.mergeProps({
@@ -35161,7 +35269,7 @@
35161
35269
  // Always display masked value in input when mask is applied
35162
35270
  val => props.mask ? mask.mask(mask.unmask(val)) : val, val => {
35163
35271
  if (props.mask) {
35164
- const valueWithoutDelimiters = removeMaskDelimiters(val);
35272
+ const valueWithoutDelimiters = val ? removeMaskDelimiters(val) : '';
35165
35273
 
35166
35274
  // E.g. mask is #-# and the input value is '2-23'
35167
35275
  // model-value should be enforced to '2-2'
@@ -37907,7 +38015,7 @@
37907
38015
  };
37908
38016
  });
37909
38017
  }
37910
- const version$1 = "3.10.5";
38018
+ const version$1 = "3.10.7";
37911
38019
  createVuetify$1.version = version$1;
37912
38020
 
37913
38021
  // Vue's inject() can only be used in setup
@@ -38205,7 +38313,7 @@
38205
38313
 
38206
38314
  /* eslint-disable local-rules/sort-imports */
38207
38315
 
38208
- const version = "3.10.5";
38316
+ const version = "3.10.7";
38209
38317
 
38210
38318
  /* eslint-disable local-rules/sort-imports */
38211
38319