vuetify 3.3.6 → 3.3.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 (83) hide show
  1. package/dist/json/attributes.json +14 -10
  2. package/dist/json/importMap.json +76 -76
  3. package/dist/json/tags.json +1 -0
  4. package/dist/json/web-types.json +26 -24
  5. package/dist/vuetify-labs.css +127 -111
  6. package/dist/vuetify-labs.d.ts +178 -76
  7. package/dist/vuetify-labs.esm.js +486 -337
  8. package/dist/vuetify-labs.esm.js.map +1 -1
  9. package/dist/vuetify-labs.js +485 -336
  10. package/dist/vuetify-labs.min.css +2 -2
  11. package/dist/vuetify.css +36 -20
  12. package/dist/vuetify.d.ts +157 -93
  13. package/dist/vuetify.esm.js +469 -326
  14. package/dist/vuetify.esm.js.map +1 -1
  15. package/dist/vuetify.js +468 -325
  16. package/dist/vuetify.js.map +1 -1
  17. package/dist/vuetify.min.css +2 -2
  18. package/dist/vuetify.min.js +688 -669
  19. package/dist/vuetify.min.js.map +1 -1
  20. package/lib/components/VAutocomplete/VAutocomplete.mjs +48 -35
  21. package/lib/components/VAutocomplete/VAutocomplete.mjs.map +1 -1
  22. package/lib/components/VBtn/VBtn.mjs +1 -1
  23. package/lib/components/VBtn/VBtn.mjs.map +1 -1
  24. package/lib/components/VCheckbox/index.d.mts +28 -16
  25. package/lib/components/VCombobox/VCombobox.mjs +48 -35
  26. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  27. package/lib/components/VField/VField.css +17 -6
  28. package/lib/components/VField/VField.sass +17 -6
  29. package/lib/components/VField/_variables.scss +2 -2
  30. package/lib/components/VIcon/VIcon.css +1 -0
  31. package/lib/components/VIcon/VIcon.sass +1 -0
  32. package/lib/components/VImg/VImg.css +4 -2
  33. package/lib/components/VImg/VImg.mjs +4 -2
  34. package/lib/components/VImg/VImg.mjs.map +1 -1
  35. package/lib/components/VImg/VImg.sass +3 -4
  36. package/lib/components/VOverlay/VOverlay.css +2 -0
  37. package/lib/components/VOverlay/VOverlay.sass +3 -1
  38. package/lib/components/VOverlay/scrollStrategies.mjs +3 -1
  39. package/lib/components/VOverlay/scrollStrategies.mjs.map +1 -1
  40. package/lib/components/VRadio/index.d.mts +14 -8
  41. package/lib/components/VRadioGroup/index.d.mts +14 -8
  42. package/lib/components/VResponsive/VResponsive.css +6 -11
  43. package/lib/components/VResponsive/VResponsive.sass +5 -10
  44. package/lib/components/VSelect/VSelect.mjs +43 -31
  45. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  46. package/lib/components/VSelect/useScrolling.mjs +69 -0
  47. package/lib/components/VSelect/useScrolling.mjs.map +1 -0
  48. package/lib/components/VSelectionControl/VSelectionControl.mjs +2 -2
  49. package/lib/components/VSelectionControl/VSelectionControl.mjs.map +1 -1
  50. package/lib/components/VSelectionControl/index.d.mts +14 -8
  51. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.mjs +4 -1
  52. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.mjs.map +1 -1
  53. package/lib/components/VSelectionControlGroup/index.d.mts +14 -8
  54. package/lib/components/VSwitch/index.d.mts +14 -8
  55. package/lib/components/VTextField/VTextField.css +5 -0
  56. package/lib/components/VTextField/VTextField.mjs +6 -2
  57. package/lib/components/VTextField/VTextField.mjs.map +1 -1
  58. package/lib/components/VTextField/VTextField.sass +5 -0
  59. package/lib/components/VTextField/_variables.scss +1 -0
  60. package/lib/components/VVirtualScroll/VVirtualScroll.mjs +50 -24
  61. package/lib/components/VVirtualScroll/VVirtualScroll.mjs.map +1 -1
  62. package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs +13 -23
  63. package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs.map +1 -1
  64. package/lib/components/VVirtualScroll/index.d.mts +37 -15
  65. package/lib/components/index.d.mts +134 -70
  66. package/lib/composables/filter.mjs +9 -7
  67. package/lib/composables/filter.mjs.map +1 -1
  68. package/lib/composables/resizeObserver.mjs +6 -1
  69. package/lib/composables/resizeObserver.mjs.map +1 -1
  70. package/lib/composables/virtual.mjs +17 -17
  71. package/lib/composables/virtual.mjs.map +1 -1
  72. package/lib/entry-bundler.mjs +1 -1
  73. package/lib/framework.mjs +1 -1
  74. package/lib/index.d.mts +23 -23
  75. package/lib/labs/VDataTable/VDataTableVirtual.mjs +12 -10
  76. package/lib/labs/VDataTable/VDataTableVirtual.mjs.map +1 -1
  77. package/lib/labs/VDataTable/composables/headers.mjs +6 -2
  78. package/lib/labs/VDataTable/composables/headers.mjs.map +1 -1
  79. package/lib/labs/VDataTable/index.d.mts +44 -6
  80. package/lib/labs/components.d.mts +44 -6
  81. package/lib/util/getScrollParent.mjs +7 -1
  82. package/lib/util/getScrollParent.mjs.map +1 -1
  83. package/package.json +2 -2
package/dist/vuetify.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.3.6
2
+ * Vuetify v3.3.7
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -1251,8 +1251,9 @@
1251
1251
  };
1252
1252
 
1253
1253
  function getScrollParent(el) {
1254
+ let includeHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1254
1255
  while (el) {
1255
- if (hasScrollbar(el)) return el;
1256
+ if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el;
1256
1257
  el = el.parentElement;
1257
1258
  }
1258
1259
  return document.scrollingElement;
@@ -1272,6 +1273,11 @@
1272
1273
  const style = window.getComputedStyle(el);
1273
1274
  return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
1274
1275
  }
1276
+ function isPotentiallyScrollable(el) {
1277
+ if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
1278
+ const style = window.getComputedStyle(el);
1279
+ return ['scroll', 'auto'].includes(style.overflowY);
1280
+ }
1275
1281
 
1276
1282
  const IN_BROWSER = typeof window !== 'undefined';
1277
1283
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
@@ -1317,13 +1323,18 @@
1317
1323
  // Types
1318
1324
 
1319
1325
  function useResizeObserver(callback) {
1326
+ let box = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'content';
1320
1327
  const resizeRef = vue.ref();
1321
1328
  const contentRect = vue.ref();
1322
1329
  if (IN_BROWSER) {
1323
1330
  const observer = new ResizeObserver(entries => {
1324
1331
  callback?.(entries, observer);
1325
1332
  if (!entries.length) return;
1326
- contentRect.value = entries[0].contentRect;
1333
+ if (box === 'content') {
1334
+ contentRect.value = entries[0].contentRect;
1335
+ } else {
1336
+ contentRect.value = entries[0].target.getBoundingClientRect();
1337
+ }
1327
1338
  });
1328
1339
  vue.onBeforeUnmount(() => {
1329
1340
  observer.disconnect();
@@ -3145,7 +3156,9 @@
3145
3156
  "class": ['v-img', {
3146
3157
  'v-img--booting': !isBooted.value
3147
3158
  }, props.class],
3148
- "style": props.style
3159
+ "style": [{
3160
+ width: convertToUnit(props.width === 'auto' ? naturalWidth.value : props.width)
3161
+ }, props.style]
3149
3162
  }, responsiveProps, {
3150
3163
  "aspectRatio": aspectRatio.value,
3151
3164
  "aria-label": props.alt,
@@ -5264,7 +5277,7 @@
5264
5277
  return Object(props.value) === props.value ? JSON.stringify(props.value, null, 0) : props.value;
5265
5278
  });
5266
5279
  function onClick(e) {
5267
- if (isDisabled.value) return;
5280
+ if (isDisabled.value || link.isLink.value && (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0 || attrs.target === '_blank')) return;
5268
5281
  link.navigate?.(e);
5269
5282
  group?.toggle();
5270
5283
  }
@@ -5603,7 +5616,10 @@
5603
5616
  const VSelectionControlGroupSymbol = Symbol.for('vuetify:selection-control-group');
5604
5617
  const makeSelectionControlGroupProps = propsFactory({
5605
5618
  color: String,
5606
- disabled: Boolean,
5619
+ disabled: {
5620
+ type: Boolean,
5621
+ default: null
5622
+ },
5607
5623
  defaultsTarget: String,
5608
5624
  error: Boolean,
5609
5625
  id: String,
@@ -5827,12 +5843,12 @@
5827
5843
  }, null), vue.createVNode("input", vue.mergeProps({
5828
5844
  "ref": input,
5829
5845
  "checked": model.value,
5830
- "disabled": props.disabled,
5846
+ "disabled": !!(props.readonly || props.disabled),
5831
5847
  "id": id.value,
5832
5848
  "onBlur": onBlur,
5833
5849
  "onFocus": onFocus,
5834
5850
  "onInput": onInput,
5835
- "aria-disabled": props.readonly,
5851
+ "aria-disabled": !!(props.readonly || props.disabled),
5836
5852
  "type": props.type,
5837
5853
  "value": trueValue.value,
5838
5854
  "name": props.name,
@@ -8703,7 +8719,9 @@
8703
8719
  scrollElements.forEach((el, i) => {
8704
8720
  el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft));
8705
8721
  el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop));
8706
- el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
8722
+ if (el !== document.documentElement) {
8723
+ el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
8724
+ }
8707
8725
  el.classList.add('v-overlay-scroll-blocked');
8708
8726
  });
8709
8727
  vue.onScopeDispose(() => {
@@ -10358,12 +10376,16 @@
10358
10376
  }]]);
10359
10377
  return vue.createVNode(vue.Fragment, null, [props.prefix && vue.createVNode("span", {
10360
10378
  "class": "v-text-field__prefix"
10361
- }, [props.prefix]), vue.createVNode("div", {
10379
+ }, [vue.createVNode("span", {
10380
+ "class": "v-text-field__prefix__text"
10381
+ }, [props.prefix])]), vue.createVNode("div", {
10362
10382
  "class": fieldClass,
10363
10383
  "data-no-activator": ""
10364
10384
  }, [slots.default ? vue.createVNode(vue.Fragment, null, [slots.default(), inputNode]) : vue.cloneVNode(inputNode)]), props.suffix && vue.createVNode("span", {
10365
10385
  "class": "v-text-field__suffix"
10366
- }, [props.suffix])]);
10386
+ }, [vue.createVNode("span", {
10387
+ "class": "v-text-field__suffix__text"
10388
+ }, [props.suffix])])]);
10367
10389
  }
10368
10390
  });
10369
10391
  },
@@ -10380,6 +10402,301 @@
10380
10402
 
10381
10403
  // Types
10382
10404
 
10405
+ const makeVVirtualScrollItemProps = propsFactory({
10406
+ renderless: Boolean,
10407
+ ...makeComponentProps()
10408
+ }, 'VVirtualScrollItem');
10409
+ const VVirtualScrollItem = genericComponent()({
10410
+ name: 'VVirtualScrollItem',
10411
+ inheritAttrs: false,
10412
+ props: makeVVirtualScrollItemProps(),
10413
+ emits: {
10414
+ 'update:height': height => true
10415
+ },
10416
+ setup(props, _ref) {
10417
+ let {
10418
+ attrs,
10419
+ emit,
10420
+ slots
10421
+ } = _ref;
10422
+ const {
10423
+ resizeRef,
10424
+ contentRect
10425
+ } = useResizeObserver(undefined, 'border');
10426
+ vue.watch(() => contentRect.value?.height, height => {
10427
+ if (height != null) emit('update:height', height);
10428
+ });
10429
+ useRender(() => props.renderless ? vue.createVNode(vue.Fragment, null, [slots.default?.({
10430
+ itemRef: resizeRef
10431
+ })]) : vue.createVNode("div", vue.mergeProps({
10432
+ "ref": resizeRef,
10433
+ "class": ['v-virtual-scroll__item', props.class],
10434
+ "style": props.style
10435
+ }, attrs), [slots.default?.()]));
10436
+ }
10437
+ });
10438
+
10439
+ // Composables
10440
+
10441
+ // Types
10442
+
10443
+ const UP = -1;
10444
+ const DOWN = 1;
10445
+ const makeVirtualProps = propsFactory({
10446
+ itemHeight: {
10447
+ type: [Number, String],
10448
+ default: 48
10449
+ }
10450
+ }, 'virtual');
10451
+ function useVirtual(props, items, offset) {
10452
+ const first = vue.shallowRef(0);
10453
+ const baseItemHeight = vue.shallowRef(props.itemHeight);
10454
+ const itemHeight = vue.computed({
10455
+ get: () => parseInt(baseItemHeight.value ?? 0, 10),
10456
+ set(val) {
10457
+ baseItemHeight.value = val;
10458
+ }
10459
+ });
10460
+ const containerRef = vue.ref();
10461
+ const {
10462
+ resizeRef,
10463
+ contentRect
10464
+ } = useResizeObserver();
10465
+ vue.watchEffect(() => {
10466
+ resizeRef.value = containerRef.value;
10467
+ });
10468
+ const display = useDisplay();
10469
+ const sizeMap = new Map();
10470
+ let sizes = Array.from({
10471
+ length: items.value.length
10472
+ });
10473
+ const visibleItems = vue.computed(() => {
10474
+ const height = (!contentRect.value || containerRef.value === document.documentElement ? display.height.value : contentRect.value.height) - (offset?.value ?? 0);
10475
+ return Math.ceil(height / itemHeight.value * 1.7 + 1);
10476
+ });
10477
+ function handleItemResize(index, height) {
10478
+ itemHeight.value = Math.max(itemHeight.value, height);
10479
+ sizes[index] = height;
10480
+ sizeMap.set(items.value[index], height);
10481
+ }
10482
+ function calculateOffset(index) {
10483
+ return sizes.slice(0, index).reduce((acc, val) => acc + (val || itemHeight.value), 0);
10484
+ }
10485
+ function calculateMidPointIndex(scrollTop) {
10486
+ const end = items.value.length;
10487
+ let middle = 0;
10488
+ let middleOffset = 0;
10489
+ while (middleOffset < scrollTop && middle < end) {
10490
+ middleOffset += sizes[middle++] || itemHeight.value;
10491
+ }
10492
+ return middle - 1;
10493
+ }
10494
+ let lastScrollTop = 0;
10495
+ function handleScroll() {
10496
+ if (!containerRef.value || !contentRect.value) return;
10497
+ const height = contentRect.value.height - 56;
10498
+ const scrollTop = containerRef.value.scrollTop;
10499
+ const direction = scrollTop < lastScrollTop ? UP : DOWN;
10500
+ const midPointIndex = calculateMidPointIndex(scrollTop + height / 2);
10501
+ const buffer = Math.round(visibleItems.value / 3);
10502
+ const firstIndex = midPointIndex - buffer;
10503
+ const lastIndex = first.value + buffer * 2 - 1;
10504
+ if (direction === UP && midPointIndex <= lastIndex) {
10505
+ first.value = clamp(firstIndex, 0, items.value.length);
10506
+ } else if (direction === DOWN && midPointIndex >= lastIndex) {
10507
+ first.value = clamp(firstIndex, 0, items.value.length - visibleItems.value);
10508
+ }
10509
+ lastScrollTop = scrollTop;
10510
+ }
10511
+ function scrollToIndex(index) {
10512
+ if (!containerRef.value) return;
10513
+ const offset = calculateOffset(index);
10514
+ containerRef.value.scrollTop = offset;
10515
+ }
10516
+ const last = vue.computed(() => Math.min(items.value.length, first.value + visibleItems.value));
10517
+ const computedItems = vue.computed(() => {
10518
+ return items.value.slice(first.value, last.value).map((item, index) => ({
10519
+ raw: item,
10520
+ index: index + first.value
10521
+ }));
10522
+ });
10523
+ const paddingTop = vue.computed(() => calculateOffset(first.value));
10524
+ const paddingBottom = vue.computed(() => calculateOffset(items.value.length) - calculateOffset(last.value));
10525
+ vue.watch(() => items.value.length, () => {
10526
+ sizes = createRange(items.value.length).map(() => itemHeight.value);
10527
+ sizeMap.forEach((height, item) => {
10528
+ const index = items.value.indexOf(item);
10529
+ if (index === -1) {
10530
+ sizeMap.delete(item);
10531
+ } else {
10532
+ sizes[index] = height;
10533
+ }
10534
+ });
10535
+ });
10536
+ return {
10537
+ containerRef,
10538
+ computedItems,
10539
+ itemHeight,
10540
+ paddingTop,
10541
+ paddingBottom,
10542
+ scrollToIndex,
10543
+ handleScroll,
10544
+ handleItemResize
10545
+ };
10546
+ }
10547
+
10548
+ // Types
10549
+
10550
+ const makeVVirtualScrollProps = propsFactory({
10551
+ items: {
10552
+ type: Array,
10553
+ default: () => []
10554
+ },
10555
+ renderless: Boolean,
10556
+ ...makeVirtualProps(),
10557
+ ...makeComponentProps(),
10558
+ ...makeDimensionProps()
10559
+ }, 'VVirtualScroll');
10560
+ const VVirtualScroll = genericComponent()({
10561
+ name: 'VVirtualScroll',
10562
+ props: makeVVirtualScrollProps(),
10563
+ setup(props, _ref) {
10564
+ let {
10565
+ slots
10566
+ } = _ref;
10567
+ const vm = getCurrentInstance('VVirtualScroll');
10568
+ const {
10569
+ dimensionStyles
10570
+ } = useDimension(props);
10571
+ const {
10572
+ containerRef,
10573
+ handleScroll,
10574
+ handleItemResize,
10575
+ scrollToIndex,
10576
+ paddingTop,
10577
+ paddingBottom,
10578
+ computedItems
10579
+ } = useVirtual(props, vue.toRef(props, 'items'));
10580
+ useToggleScope(() => props.renderless, () => {
10581
+ vue.onMounted(() => {
10582
+ containerRef.value = getScrollParent(vm.vnode.el, true);
10583
+ containerRef.value?.addEventListener('scroll', handleScroll);
10584
+ });
10585
+ vue.onScopeDispose(() => {
10586
+ containerRef.value?.removeEventListener('scroll', handleScroll);
10587
+ });
10588
+ });
10589
+ useRender(() => {
10590
+ const children = computedItems.value.map(item => vue.createVNode(VVirtualScrollItem, {
10591
+ "key": item.index,
10592
+ "renderless": props.renderless,
10593
+ "onUpdate:height": height => handleItemResize(item.index, height)
10594
+ }, {
10595
+ default: slotProps => slots.default?.({
10596
+ item: item.raw,
10597
+ index: item.index,
10598
+ ...slotProps
10599
+ })
10600
+ }));
10601
+ return props.renderless ? vue.createVNode(vue.Fragment, null, [vue.createVNode("div", {
10602
+ "class": "v-virtual-scroll__spacer",
10603
+ "style": {
10604
+ paddingTop: convertToUnit(paddingTop.value)
10605
+ }
10606
+ }, null), children, vue.createVNode("div", {
10607
+ "class": "v-virtual-scroll__spacer",
10608
+ "style": {
10609
+ paddingBottom: convertToUnit(paddingBottom.value)
10610
+ }
10611
+ }, null)]) : vue.createVNode("div", {
10612
+ "ref": containerRef,
10613
+ "class": ['v-virtual-scroll', props.class],
10614
+ "onScroll": handleScroll,
10615
+ "style": [dimensionStyles.value, props.style]
10616
+ }, [vue.createVNode("div", {
10617
+ "class": "v-virtual-scroll__container",
10618
+ "style": {
10619
+ paddingTop: convertToUnit(paddingTop.value),
10620
+ paddingBottom: convertToUnit(paddingBottom.value)
10621
+ }
10622
+ }, [children])]);
10623
+ });
10624
+ return {
10625
+ scrollToIndex
10626
+ };
10627
+ }
10628
+ });
10629
+
10630
+ // Utilities
10631
+
10632
+ // Types
10633
+
10634
+ function useScrolling(listRef, textFieldRef) {
10635
+ const isScrolling = vue.shallowRef(false);
10636
+ let scrollTimeout;
10637
+ function onListScroll(e) {
10638
+ cancelAnimationFrame(scrollTimeout);
10639
+ isScrolling.value = true;
10640
+ scrollTimeout = requestAnimationFrame(() => {
10641
+ scrollTimeout = requestAnimationFrame(() => {
10642
+ isScrolling.value = false;
10643
+ });
10644
+ });
10645
+ }
10646
+ async function finishScrolling() {
10647
+ await new Promise(resolve => requestAnimationFrame(resolve));
10648
+ await new Promise(resolve => requestAnimationFrame(resolve));
10649
+ await new Promise(resolve => requestAnimationFrame(resolve));
10650
+ await new Promise(resolve => {
10651
+ if (isScrolling.value) {
10652
+ const stop = vue.watch(isScrolling, () => {
10653
+ stop();
10654
+ resolve();
10655
+ });
10656
+ } else resolve();
10657
+ });
10658
+ }
10659
+ async function onListKeydown(e) {
10660
+ if (e.key === 'Tab') {
10661
+ textFieldRef.value?.focus();
10662
+ }
10663
+ if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return;
10664
+ const el = listRef.value?.$el;
10665
+ if (!el) return;
10666
+ if (e.key === 'Home' || e.key === 'End') {
10667
+ el.scrollTo({
10668
+ top: e.key === 'Home' ? 0 : el.scrollHeight,
10669
+ behavior: 'smooth'
10670
+ });
10671
+ }
10672
+ await finishScrolling();
10673
+ const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)');
10674
+ if (e.key === 'PageDown' || e.key === 'Home') {
10675
+ const top = el.getBoundingClientRect().top;
10676
+ for (const child of children) {
10677
+ if (child.getBoundingClientRect().top >= top) {
10678
+ child.focus();
10679
+ break;
10680
+ }
10681
+ }
10682
+ } else {
10683
+ const bottom = el.getBoundingClientRect().bottom;
10684
+ for (const child of [...children].reverse()) {
10685
+ if (child.getBoundingClientRect().bottom <= bottom) {
10686
+ child.focus();
10687
+ break;
10688
+ }
10689
+ }
10690
+ }
10691
+ }
10692
+ return {
10693
+ onListScroll,
10694
+ onListKeydown
10695
+ };
10696
+ }
10697
+
10698
+ // Types
10699
+
10383
10700
  const makeSelectProps = propsFactory({
10384
10701
  chips: Boolean,
10385
10702
  closableChips: Boolean,
@@ -10471,6 +10788,10 @@
10471
10788
  });
10472
10789
  const menuDisabled = vue.computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
10473
10790
  const listRef = vue.ref();
10791
+ const {
10792
+ onListScroll,
10793
+ onListKeydown
10794
+ } = useScrolling(listRef, vTextFieldRef);
10474
10795
  function onClear(e) {
10475
10796
  if (props.openOnClear) {
10476
10797
  menu.value = true;
@@ -10517,11 +10838,6 @@
10517
10838
  model.value = [item];
10518
10839
  }
10519
10840
  }
10520
- function onListKeydown(e) {
10521
- if (e.key === 'Tab') {
10522
- vTextFieldRef.value?.focus();
10523
- }
10524
- }
10525
10841
  function select(item) {
10526
10842
  if (props.multiple) {
10527
10843
  const index = selected.value.findIndex(selection => props.valueComparator(selection, item.value));
@@ -10604,34 +10920,46 @@
10604
10920
  "onMousedown": e => e.preventDefault(),
10605
10921
  "onKeydown": onListKeydown,
10606
10922
  "onFocusin": onFocusin,
10923
+ "onScrollPassive": onListScroll,
10607
10924
  "tabindex": "-1"
10608
10925
  }, {
10609
10926
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
10610
10927
  "title": t(props.noDataText)
10611
- }, null)), displayItems.value.map((item, index) => {
10612
- const itemProps = vue.mergeProps(item.props, {
10613
- key: index,
10614
- onClick: () => select(item)
10615
- });
10616
- return slots.item?.({
10617
- item,
10618
- index,
10619
- props: itemProps
10620
- }) ?? vue.createVNode(VListItem, itemProps, {
10621
- prepend: _ref2 => {
10622
- let {
10623
- isSelected
10624
- } = _ref2;
10625
- return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
10626
- "key": item.value,
10627
- "modelValue": isSelected,
10628
- "ripple": false,
10629
- "tabindex": "-1"
10630
- }, null) : undefined, item.props.prependIcon && vue.createVNode(VIcon, {
10631
- "icon": item.props.prependIcon
10632
- }, null)]);
10633
- }
10634
- });
10928
+ }, null)), vue.createVNode(VVirtualScroll, {
10929
+ "renderless": true,
10930
+ "items": displayItems.value
10931
+ }, {
10932
+ default: _ref2 => {
10933
+ let {
10934
+ item,
10935
+ index,
10936
+ itemRef
10937
+ } = _ref2;
10938
+ const itemProps = vue.mergeProps(item.props, {
10939
+ ref: itemRef,
10940
+ key: index,
10941
+ onClick: () => select(item)
10942
+ });
10943
+ return slots.item?.({
10944
+ item,
10945
+ index,
10946
+ props: itemProps
10947
+ }) ?? vue.createVNode(VListItem, itemProps, {
10948
+ prepend: _ref3 => {
10949
+ let {
10950
+ isSelected
10951
+ } = _ref3;
10952
+ return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
10953
+ "key": item.value,
10954
+ "modelValue": isSelected,
10955
+ "ripple": false,
10956
+ "tabindex": "-1"
10957
+ }, null) : undefined, item.props.prependIcon && vue.createVNode(VIcon, {
10958
+ "icon": item.props.prependIcon
10959
+ }, null)]);
10960
+ }
10961
+ });
10962
+ }
10635
10963
  }), slots['append-item']?.()]
10636
10964
  })]
10637
10965
  }), selections.value.map((item, index) => {
@@ -10769,14 +11097,12 @@
10769
11097
  return array;
10770
11098
  }
10771
11099
  function useFilter(props, items, query, options) {
10772
- const strQuery = vue.computed(() => typeof query?.value !== 'string' && typeof query?.value !== 'number' ? '' : String(query.value));
10773
11100
  const filteredItems = vue.ref([]);
10774
11101
  const filteredMatches = vue.ref(new Map());
10775
11102
  const transformedItems = vue.computed(() => options?.transform ? vue.unref(items).map(options?.transform) : vue.unref(items));
10776
11103
  vue.watchEffect(() => {
10777
- filteredItems.value = [];
10778
- filteredMatches.value = new Map();
10779
- const results = filterItems(transformedItems.value, strQuery.value, {
11104
+ const strQuery = typeof vue.toValue(query) !== 'string' && typeof vue.toValue(query) !== 'number' ? '' : String(vue.toValue(query));
11105
+ const results = filterItems(transformedItems.value, strQuery, {
10780
11106
  customKeyFilter: props.customKeyFilter,
10781
11107
  default: props.customFilter,
10782
11108
  filterKeys: props.filterKeys,
@@ -10784,15 +11110,19 @@
10784
11110
  noFilter: props.noFilter
10785
11111
  });
10786
11112
  const originalItems = vue.unref(items);
11113
+ const _filteredItems = [];
11114
+ const _filteredMatches = new Map();
10787
11115
  results.forEach(_ref => {
10788
11116
  let {
10789
11117
  index,
10790
11118
  matches
10791
11119
  } = _ref;
10792
11120
  const item = originalItems[index];
10793
- filteredItems.value.push(item);
10794
- filteredMatches.value.set(item.value, matches);
11121
+ _filteredItems.push(item);
11122
+ _filteredMatches.set(item.value, matches);
10795
11123
  });
11124
+ filteredItems.value = _filteredItems;
11125
+ filteredMatches.value = _filteredMatches;
10796
11126
  });
10797
11127
  function getMatches(item) {
10798
11128
  return filteredMatches.value.get(item.value);
@@ -10882,7 +11212,7 @@
10882
11212
  const {
10883
11213
  filteredItems,
10884
11214
  getMatches
10885
- } = useFilter(props, items, vue.computed(() => isPristine.value ? undefined : search.value));
11215
+ } = useFilter(props, items, () => isPristine.value ? '' : search.value);
10886
11216
  const selections = vue.computed(() => {
10887
11217
  return model.value.map(v => {
10888
11218
  return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
@@ -10902,6 +11232,10 @@
10902
11232
  });
10903
11233
  const menuDisabled = vue.computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
10904
11234
  const listRef = vue.ref();
11235
+ const {
11236
+ onListScroll,
11237
+ onListKeydown
11238
+ } = useScrolling(listRef, vTextFieldRef);
10905
11239
  function onClear(e) {
10906
11240
  if (props.openOnClear) {
10907
11241
  menu.value = true;
@@ -10975,11 +11309,6 @@
10975
11309
  }
10976
11310
  }
10977
11311
  }
10978
- function onListKeydown(e) {
10979
- if (e.key === 'Tab') {
10980
- vTextFieldRef.value?.focus();
10981
- }
10982
- }
10983
11312
  function onInput(e) {
10984
11313
  search.value = e.target.value;
10985
11314
  }
@@ -11098,38 +11427,50 @@
11098
11427
  "onKeydown": onListKeydown,
11099
11428
  "onFocusin": onFocusin,
11100
11429
  "onFocusout": onFocusout,
11430
+ "onScrollPassive": onListScroll,
11101
11431
  "tabindex": "-1"
11102
11432
  }, {
11103
11433
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
11104
11434
  "title": t(props.noDataText)
11105
- }, null)), displayItems.value.map((item, index) => {
11106
- const itemProps = vue.mergeProps(item.props, {
11107
- key: index,
11108
- active: highlightFirst.value && index === 0 ? true : undefined,
11109
- onClick: () => select(item)
11110
- });
11111
- return slots.item?.({
11112
- item,
11113
- index,
11114
- props: itemProps
11115
- }) ?? vue.createVNode(VListItem, itemProps, {
11116
- prepend: _ref3 => {
11117
- let {
11118
- isSelected
11119
- } = _ref3;
11120
- return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
11121
- "key": item.value,
11122
- "modelValue": isSelected,
11123
- "ripple": false,
11124
- "tabindex": "-1"
11125
- }, null) : undefined, item.props.prependIcon && vue.createVNode(VIcon, {
11126
- "icon": item.props.prependIcon
11127
- }, null)]);
11128
- },
11129
- title: () => {
11130
- return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
11131
- }
11132
- });
11435
+ }, null)), vue.createVNode(VVirtualScroll, {
11436
+ "renderless": true,
11437
+ "items": displayItems.value
11438
+ }, {
11439
+ default: _ref3 => {
11440
+ let {
11441
+ item,
11442
+ index,
11443
+ itemRef
11444
+ } = _ref3;
11445
+ const itemProps = vue.mergeProps(item.props, {
11446
+ ref: itemRef,
11447
+ key: index,
11448
+ active: highlightFirst.value && index === 0 ? true : undefined,
11449
+ onClick: () => select(item)
11450
+ });
11451
+ return slots.item?.({
11452
+ item,
11453
+ index,
11454
+ props: itemProps
11455
+ }) ?? vue.createVNode(VListItem, itemProps, {
11456
+ prepend: _ref4 => {
11457
+ let {
11458
+ isSelected
11459
+ } = _ref4;
11460
+ return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
11461
+ "key": item.value,
11462
+ "modelValue": isSelected,
11463
+ "ripple": false,
11464
+ "tabindex": "-1"
11465
+ }, null) : undefined, item.props.prependIcon && vue.createVNode(VIcon, {
11466
+ "icon": item.props.prependIcon
11467
+ }, null)]);
11468
+ },
11469
+ title: () => {
11470
+ return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
11471
+ }
11472
+ });
11473
+ }
11133
11474
  }), slots['append-item']?.()]
11134
11475
  })]
11135
11476
  }), selections.value.map((item, index) => {
@@ -14423,7 +14764,7 @@
14423
14764
  const {
14424
14765
  filteredItems,
14425
14766
  getMatches
14426
- } = useFilter(props, items, vue.computed(() => isPristine.value ? undefined : search.value));
14767
+ } = useFilter(props, items, () => isPristine.value ? '' : search.value);
14427
14768
  const selections = vue.computed(() => {
14428
14769
  return model.value.map(v => {
14429
14770
  return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
@@ -14443,6 +14784,10 @@
14443
14784
  });
14444
14785
  const menuDisabled = vue.computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
14445
14786
  const listRef = vue.ref();
14787
+ const {
14788
+ onListScroll,
14789
+ onListKeydown
14790
+ } = useScrolling(listRef, vTextFieldRef);
14446
14791
  function onClear(e) {
14447
14792
  cleared = true;
14448
14793
  if (props.openOnClear) {
@@ -14520,11 +14865,6 @@
14520
14865
  search.value = '';
14521
14866
  }
14522
14867
  }
14523
- function onListKeydown(e) {
14524
- if (e.key === 'Tab') {
14525
- vTextFieldRef.value?.focus();
14526
- }
14527
- }
14528
14868
  function onAfterLeave() {
14529
14869
  if (isFocused.value) {
14530
14870
  isPristine.value = true;
@@ -14635,38 +14975,50 @@
14635
14975
  "onKeydown": onListKeydown,
14636
14976
  "onFocusin": onFocusin,
14637
14977
  "onFocusout": onFocusout,
14978
+ "onScrollPassive": onListScroll,
14638
14979
  "tabindex": "-1"
14639
14980
  }, {
14640
14981
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? vue.createVNode(VListItem, {
14641
14982
  "title": t(props.noDataText)
14642
- }, null)), displayItems.value.map((item, index) => {
14643
- const itemProps = vue.mergeProps(item.props, {
14644
- key: index,
14645
- active: highlightFirst.value && index === 0 ? true : undefined,
14646
- onClick: () => select(item)
14647
- });
14648
- return slots.item?.({
14649
- item,
14650
- index,
14651
- props: itemProps
14652
- }) ?? vue.createVNode(VListItem, itemProps, {
14653
- prepend: _ref3 => {
14654
- let {
14655
- isSelected
14656
- } = _ref3;
14657
- return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
14658
- "key": item.value,
14659
- "modelValue": isSelected,
14660
- "ripple": false,
14661
- "tabindex": "-1"
14662
- }, null) : undefined, item.props.prependIcon && vue.createVNode(VIcon, {
14663
- "icon": item.props.prependIcon
14664
- }, null)]);
14665
- },
14666
- title: () => {
14667
- return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
14668
- }
14669
- });
14983
+ }, null)), vue.createVNode(VVirtualScroll, {
14984
+ "renderless": true,
14985
+ "items": displayItems.value
14986
+ }, {
14987
+ default: _ref3 => {
14988
+ let {
14989
+ item,
14990
+ index,
14991
+ itemRef
14992
+ } = _ref3;
14993
+ const itemProps = vue.mergeProps(item.props, {
14994
+ ref: itemRef,
14995
+ key: index,
14996
+ active: highlightFirst.value && index === 0 ? true : undefined,
14997
+ onClick: () => select(item)
14998
+ });
14999
+ return slots.item?.({
15000
+ item,
15001
+ index,
15002
+ props: itemProps
15003
+ }) ?? vue.createVNode(VListItem, itemProps, {
15004
+ prepend: _ref4 => {
15005
+ let {
15006
+ isSelected
15007
+ } = _ref4;
15008
+ return vue.createVNode(vue.Fragment, null, [props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
15009
+ "key": item.value,
15010
+ "modelValue": isSelected,
15011
+ "ripple": false,
15012
+ "tabindex": "-1"
15013
+ }, null) : undefined, item.props.prependIcon && vue.createVNode(VIcon, {
15014
+ "icon": item.props.prependIcon
15015
+ }, null)]);
15016
+ },
15017
+ title: () => {
15018
+ return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
15019
+ }
15020
+ });
15021
+ }
14670
15022
  }), slots['append-item']?.()]
14671
15023
  })]
14672
15024
  }), selections.value.map((item, index) => {
@@ -19010,215 +19362,6 @@
19010
19362
  }
19011
19363
  });
19012
19364
 
19013
- const makeVVirtualScrollItemProps = propsFactory({
19014
- dynamicHeight: Boolean,
19015
- renderless: Boolean,
19016
- ...makeComponentProps()
19017
- }, 'VVirtualScrollItem');
19018
- const VVirtualScrollItem = genericComponent()({
19019
- name: 'VVirtualScrollItem',
19020
- props: makeVVirtualScrollItemProps(),
19021
- emits: {
19022
- 'update:height': height => true
19023
- },
19024
- setup(props, _ref) {
19025
- let {
19026
- emit,
19027
- slots
19028
- } = _ref;
19029
- const {
19030
- resizeRef,
19031
- contentRect
19032
- } = useResizeObserver();
19033
- useToggleScope(() => props.dynamicHeight, () => {
19034
- vue.watch(() => contentRect.value?.height, height => {
19035
- if (height != null) emit('update:height', height);
19036
- });
19037
- });
19038
- function updateHeight() {
19039
- if (props.dynamicHeight && contentRect.value) {
19040
- emit('update:height', contentRect.value.height);
19041
- }
19042
- }
19043
- vue.onUpdated(updateHeight);
19044
- useRender(() => props.renderless ? vue.createVNode(vue.Fragment, null, [slots.default?.({
19045
- props: {
19046
- ref: props.dynamicHeight ? resizeRef : undefined
19047
- }
19048
- })]) : vue.createVNode("div", {
19049
- "ref": props.dynamicHeight ? resizeRef : undefined,
19050
- "class": ['v-virtual-scroll__item', props.class],
19051
- "style": props.style
19052
- }, [slots.default?.()]));
19053
- }
19054
- });
19055
-
19056
- // Composables
19057
-
19058
- // Types
19059
-
19060
- const UP = -1;
19061
- const DOWN = 1;
19062
- const makeVirtualProps = propsFactory({
19063
- itemHeight: [Number, String]
19064
- }, 'virtual');
19065
- function useVirtual(props, items, offset) {
19066
- const first = vue.shallowRef(0);
19067
- const baseItemHeight = vue.shallowRef(props.itemHeight);
19068
- const itemHeight = vue.computed({
19069
- get: () => parseInt(baseItemHeight.value ?? 0, 10),
19070
- set(val) {
19071
- baseItemHeight.value = val;
19072
- }
19073
- });
19074
- const containerRef = vue.ref();
19075
- const {
19076
- resizeRef,
19077
- contentRect
19078
- } = useResizeObserver();
19079
- vue.watchEffect(() => {
19080
- resizeRef.value = containerRef.value;
19081
- });
19082
- const display = useDisplay();
19083
- const sizeMap = new Map();
19084
- let sizes = createRange(items.value.length).map(() => itemHeight.value);
19085
- const visibleItems = vue.computed(() => {
19086
- const height = (contentRect.value?.height ?? display.height.value) - (offset?.value ?? 0);
19087
- return itemHeight.value ? Math.max(12, Math.ceil(height / itemHeight.value * 1.7 + 1)) : 12;
19088
- });
19089
- function handleItemResize(index, height) {
19090
- itemHeight.value = Math.max(itemHeight.value, height);
19091
- sizes[index] = height;
19092
- sizeMap.set(items.value[index], height);
19093
- }
19094
- function calculateOffset(index) {
19095
- return sizes.slice(0, index).reduce((curr, value) => curr + (value || itemHeight.value), 0);
19096
- }
19097
- function calculateMidPointIndex(scrollTop) {
19098
- const end = items.value.length;
19099
- let middle = 0;
19100
- let middleOffset = 0;
19101
- while (middleOffset < scrollTop && middle < end) {
19102
- middleOffset += sizes[middle++] || itemHeight.value;
19103
- }
19104
- return middle - 1;
19105
- }
19106
- let lastScrollTop = 0;
19107
- function handleScroll() {
19108
- if (!containerRef.value || !contentRect.value) return;
19109
- const height = contentRect.value.height - 56;
19110
- const scrollTop = containerRef.value.scrollTop;
19111
- const direction = scrollTop < lastScrollTop ? UP : DOWN;
19112
- const midPointIndex = calculateMidPointIndex(scrollTop + height / 2);
19113
- const buffer = Math.round(visibleItems.value / 3);
19114
- const firstIndex = midPointIndex - buffer;
19115
- const lastIndex = first.value + buffer * 2 - 1;
19116
- if (direction === UP && midPointIndex <= lastIndex) {
19117
- first.value = clamp(firstIndex, 0, items.value.length);
19118
- } else if (direction === DOWN && midPointIndex >= lastIndex) {
19119
- first.value = clamp(firstIndex, 0, items.value.length - visibleItems.value);
19120
- }
19121
- lastScrollTop = scrollTop;
19122
- }
19123
- function scrollToIndex(index) {
19124
- if (!containerRef.value) return;
19125
- const offset = calculateOffset(index);
19126
- containerRef.value.scrollTop = offset;
19127
- }
19128
- const allItems = vue.computed(() => items.value.map((item, index) => ({
19129
- raw: item,
19130
- index
19131
- })));
19132
- const last = vue.computed(() => Math.min(items.value.length, first.value + visibleItems.value));
19133
- const computedItems = vue.computed(() => allItems.value.slice(first.value, last.value));
19134
- const paddingTop = vue.computed(() => calculateOffset(first.value));
19135
- const paddingBottom = vue.computed(() => calculateOffset(items.value.length) - calculateOffset(last.value));
19136
- vue.onMounted(() => {
19137
- if (!itemHeight.value) {
19138
- // If itemHeight prop is not set, then calculate an estimated height from the average of inital items
19139
- itemHeight.value = sizes.slice(first.value, last.value).reduce((curr, height) => curr + height, 0) / visibleItems.value;
19140
- }
19141
- });
19142
- vue.watch(() => items.value.length, () => {
19143
- sizes = createRange(items.value.length).map(() => itemHeight.value);
19144
- sizeMap.forEach((height, item) => {
19145
- const index = items.value.indexOf(item);
19146
- if (index === -1) {
19147
- sizeMap.delete(item);
19148
- } else {
19149
- sizes[index] = height;
19150
- }
19151
- });
19152
- });
19153
- return {
19154
- containerRef,
19155
- computedItems,
19156
- itemHeight,
19157
- paddingTop,
19158
- paddingBottom,
19159
- scrollToIndex,
19160
- handleScroll,
19161
- handleItemResize
19162
- };
19163
- }
19164
-
19165
- // Types
19166
-
19167
- const makeVVirtualScrollProps = propsFactory({
19168
- items: {
19169
- type: Array,
19170
- default: () => []
19171
- },
19172
- ...makeVirtualProps(),
19173
- ...makeComponentProps(),
19174
- ...makeDimensionProps()
19175
- }, 'VVirtualScroll');
19176
- const VVirtualScroll = genericComponent()({
19177
- name: 'VVirtualScroll',
19178
- props: makeVVirtualScrollProps(),
19179
- setup(props, _ref) {
19180
- let {
19181
- slots
19182
- } = _ref;
19183
- const {
19184
- dimensionStyles
19185
- } = useDimension(props);
19186
- const {
19187
- containerRef,
19188
- handleScroll,
19189
- handleItemResize,
19190
- scrollToIndex,
19191
- paddingTop,
19192
- paddingBottom,
19193
- computedItems
19194
- } = useVirtual(props, vue.toRef(props, 'items'));
19195
- useRender(() => vue.createVNode("div", {
19196
- "ref": containerRef,
19197
- "class": ['v-virtual-scroll', props.class],
19198
- "onScroll": handleScroll,
19199
- "style": [dimensionStyles.value, props.style]
19200
- }, [vue.createVNode("div", {
19201
- "class": "v-virtual-scroll__container",
19202
- "style": {
19203
- paddingTop: convertToUnit(paddingTop.value),
19204
- paddingBottom: convertToUnit(paddingBottom.value)
19205
- }
19206
- }, [computedItems.value.map(item => vue.createVNode(VVirtualScrollItem, {
19207
- "key": item.index,
19208
- "dynamicHeight": !props.itemHeight,
19209
- "onUpdate:height": height => handleItemResize(item.index, height)
19210
- }, {
19211
- default: () => [slots.default?.({
19212
- item: item.raw,
19213
- index: item.index
19214
- })]
19215
- }))])]));
19216
- return {
19217
- scrollToIndex
19218
- };
19219
- }
19220
- });
19221
-
19222
19365
  var components = /*#__PURE__*/Object.freeze({
19223
19366
  __proto__: null,
19224
19367
  VAlert: VAlert,
@@ -20017,7 +20160,7 @@
20017
20160
  date
20018
20161
  };
20019
20162
  }
20020
- const version$1 = "3.3.6";
20163
+ const version$1 = "3.3.7";
20021
20164
  createVuetify$1.version = version$1;
20022
20165
 
20023
20166
  // Vue's inject() can only be used in setup
@@ -20042,7 +20185,7 @@
20042
20185
  ...options
20043
20186
  });
20044
20187
  };
20045
- const version = "3.3.6";
20188
+ const version = "3.3.7";
20046
20189
  createVuetify.version = version;
20047
20190
 
20048
20191
  exports.components = components;