vuetify 3.3.6 → 3.3.8

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/dist/json/attributes.json +15 -11
  2. package/dist/json/importMap.json +44 -44
  3. package/dist/json/tags.json +1 -0
  4. package/dist/json/web-types.json +27 -25
  5. package/dist/vuetify-labs.css +72 -55
  6. package/dist/vuetify-labs.d.ts +178 -76
  7. package/dist/vuetify-labs.esm.js +548 -397
  8. package/dist/vuetify-labs.esm.js.map +1 -1
  9. package/dist/vuetify-labs.js +547 -396
  10. package/dist/vuetify-labs.min.css +2 -2
  11. package/dist/vuetify.css +50 -33
  12. package/dist/vuetify.d.ts +145 -81
  13. package/dist/vuetify.esm.js +531 -386
  14. package/dist/vuetify.esm.js.map +1 -1
  15. package/dist/vuetify.js +530 -385
  16. package/dist/vuetify.js.map +1 -1
  17. package/dist/vuetify.min.css +2 -2
  18. package/dist/vuetify.min.js +700 -680
  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/VCarousel/VCarousel.mjs +58 -57
  25. package/lib/components/VCarousel/VCarousel.mjs.map +1 -1
  26. package/lib/components/VCheckbox/index.d.mts +28 -16
  27. package/lib/components/VCombobox/VCombobox.mjs +48 -35
  28. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  29. package/lib/components/VField/VField.css +18 -6
  30. package/lib/components/VField/VField.sass +18 -6
  31. package/lib/components/VField/_variables.scss +2 -2
  32. package/lib/components/VIcon/VIcon.css +1 -0
  33. package/lib/components/VIcon/VIcon.sass +1 -0
  34. package/lib/components/VImg/VImg.css +4 -2
  35. package/lib/components/VImg/VImg.mjs +4 -2
  36. package/lib/components/VImg/VImg.mjs.map +1 -1
  37. package/lib/components/VImg/VImg.sass +3 -4
  38. package/lib/components/VOverlay/VOverlay.css +2 -0
  39. package/lib/components/VOverlay/VOverlay.mjs +2 -2
  40. package/lib/components/VOverlay/VOverlay.mjs.map +1 -1
  41. package/lib/components/VOverlay/VOverlay.sass +3 -1
  42. package/lib/components/VOverlay/scrollStrategies.mjs +3 -1
  43. package/lib/components/VOverlay/scrollStrategies.mjs.map +1 -1
  44. package/lib/components/VRadio/index.d.mts +14 -8
  45. package/lib/components/VRadioGroup/index.d.mts +14 -8
  46. package/lib/components/VResponsive/VResponsive.css +6 -11
  47. package/lib/components/VResponsive/VResponsive.sass +5 -10
  48. package/lib/components/VSelect/VSelect.mjs +43 -31
  49. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  50. package/lib/components/VSelect/useScrolling.mjs +69 -0
  51. package/lib/components/VSelect/useScrolling.mjs.map +1 -0
  52. package/lib/components/VSelectionControl/VSelectionControl.mjs +2 -2
  53. package/lib/components/VSelectionControl/VSelectionControl.mjs.map +1 -1
  54. package/lib/components/VSelectionControl/index.d.mts +14 -8
  55. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.mjs +4 -1
  56. package/lib/components/VSelectionControlGroup/VSelectionControlGroup.mjs.map +1 -1
  57. package/lib/components/VSelectionControlGroup/index.d.mts +14 -8
  58. package/lib/components/VSwitch/index.d.mts +14 -8
  59. package/lib/components/VTextField/VTextField.css +5 -0
  60. package/lib/components/VTextField/VTextField.mjs +6 -2
  61. package/lib/components/VTextField/VTextField.mjs.map +1 -1
  62. package/lib/components/VTextField/VTextField.sass +5 -0
  63. package/lib/components/VTextField/_variables.scss +1 -0
  64. package/lib/components/VVirtualScroll/VVirtualScroll.mjs +50 -24
  65. package/lib/components/VVirtualScroll/VVirtualScroll.mjs.map +1 -1
  66. package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs +13 -23
  67. package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs.map +1 -1
  68. package/lib/components/VVirtualScroll/index.d.mts +37 -15
  69. package/lib/components/index.d.mts +134 -70
  70. package/lib/composables/filter.mjs +9 -6
  71. package/lib/composables/filter.mjs.map +1 -1
  72. package/lib/composables/resizeObserver.mjs +6 -1
  73. package/lib/composables/resizeObserver.mjs.map +1 -1
  74. package/lib/composables/theme.mjs +2 -2
  75. package/lib/composables/theme.mjs.map +1 -1
  76. package/lib/composables/virtual.mjs +17 -17
  77. package/lib/composables/virtual.mjs.map +1 -1
  78. package/lib/entry-bundler.mjs +1 -1
  79. package/lib/framework.mjs +1 -1
  80. package/lib/index.d.mts +11 -11
  81. package/lib/labs/VDataTable/VDataTableVirtual.mjs +12 -10
  82. package/lib/labs/VDataTable/VDataTableVirtual.mjs.map +1 -1
  83. package/lib/labs/VDataTable/composables/headers.mjs +6 -2
  84. package/lib/labs/VDataTable/composables/headers.mjs.map +1 -1
  85. package/lib/labs/VDataTable/index.d.mts +44 -6
  86. package/lib/labs/components.d.mts +44 -6
  87. package/lib/util/getScrollParent.mjs +7 -1
  88. package/lib/util/getScrollParent.mjs.map +1 -1
  89. package/package.json +2 -2
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * Vuetify v3.3.6
2
+ * Vuetify v3.3.8
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
- import { Fragment, reactive, computed, watchEffect, toRefs, capitalize, warn, watch, onScopeDispose, effectScope, ref, unref, provide, shallowRef, inject as inject$1, defineComponent as defineComponent$1, camelize, h, getCurrentInstance as getCurrentInstance$1, onBeforeUnmount, readonly, onDeactivated, onActivated, onMounted, toRaw, createVNode, TransitionGroup, Transition, mergeProps, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, isRef, toRef, Text, resolveDynamicComponent, Teleport, cloneVNode, createTextVNode, onBeforeUpdate, vModelText, onUpdated, withModifiers } from 'vue';
7
+ import { Fragment, reactive, computed, watchEffect, toRefs, capitalize, warn, watch, onScopeDispose, effectScope, ref, unref, provide, shallowRef, inject as inject$1, defineComponent as defineComponent$1, camelize, h, getCurrentInstance as getCurrentInstance$1, onBeforeUnmount, readonly, onDeactivated, onActivated, onMounted, toRaw, createVNode, TransitionGroup, Transition, mergeProps, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, isRef, toRef, Text, resolveDynamicComponent, Teleport, cloneVNode, createTextVNode, onBeforeUpdate, vModelText, withModifiers } from 'vue';
8
8
 
9
9
  // Types
10
10
  // eslint-disable-line vue/prefer-import-from-vue
@@ -1254,8 +1254,9 @@ getUid.reset = () => {
1254
1254
  };
1255
1255
 
1256
1256
  function getScrollParent(el) {
1257
+ let includeHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1257
1258
  while (el) {
1258
- if (hasScrollbar(el)) return el;
1259
+ if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el;
1259
1260
  el = el.parentElement;
1260
1261
  }
1261
1262
  return document.scrollingElement;
@@ -1275,6 +1276,11 @@ function hasScrollbar(el) {
1275
1276
  const style = window.getComputedStyle(el);
1276
1277
  return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
1277
1278
  }
1279
+ function isPotentiallyScrollable(el) {
1280
+ if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
1281
+ const style = window.getComputedStyle(el);
1282
+ return ['scroll', 'auto'].includes(style.overflowY);
1283
+ }
1278
1284
 
1279
1285
  const IN_BROWSER = typeof window !== 'undefined';
1280
1286
  const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
@@ -1320,13 +1326,18 @@ function useRender(render) {
1320
1326
  // Types
1321
1327
 
1322
1328
  function useResizeObserver(callback) {
1329
+ let box = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'content';
1323
1330
  const resizeRef = ref();
1324
1331
  const contentRect = ref();
1325
1332
  if (IN_BROWSER) {
1326
1333
  const observer = new ResizeObserver(entries => {
1327
1334
  callback?.(entries, observer);
1328
1335
  if (!entries.length) return;
1329
- contentRect.value = entries[0].contentRect;
1336
+ if (box === 'content') {
1337
+ contentRect.value = entries[0].contentRect;
1338
+ } else {
1339
+ contentRect.value = entries[0].target.getBoundingClientRect();
1340
+ }
1330
1341
  });
1331
1342
  onBeforeUnmount(() => {
1332
1343
  observer.disconnect();
@@ -2150,7 +2161,7 @@ function parseThemeOptions() {
2150
2161
 
2151
2162
  // Composables
2152
2163
  function createTheme(options) {
2153
- const parsedOptions = reactive(parseThemeOptions(options));
2164
+ const parsedOptions = parseThemeOptions(options);
2154
2165
  const name = ref(parsedOptions.defaultTheme);
2155
2166
  const themes = ref(parsedOptions.themes);
2156
2167
  const computedThemes = computed(() => {
@@ -3148,7 +3159,9 @@ const VImg = genericComponent()({
3148
3159
  "class": ['v-img', {
3149
3160
  'v-img--booting': !isBooted.value
3150
3161
  }, props.class],
3151
- "style": props.style
3162
+ "style": [{
3163
+ width: convertToUnit(props.width === 'auto' ? naturalWidth.value : props.width)
3164
+ }, props.style]
3152
3165
  }, responsiveProps, {
3153
3166
  "aspectRatio": aspectRatio.value,
3154
3167
  "aria-label": props.alt,
@@ -5267,7 +5280,7 @@ const VBtn = genericComponent()({
5267
5280
  return Object(props.value) === props.value ? JSON.stringify(props.value, null, 0) : props.value;
5268
5281
  });
5269
5282
  function onClick(e) {
5270
- if (isDisabled.value) return;
5283
+ if (isDisabled.value || link.isLink.value && (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0 || attrs.target === '_blank')) return;
5271
5284
  link.navigate?.(e);
5272
5285
  group?.toggle();
5273
5286
  }
@@ -5606,7 +5619,10 @@ const VLabel = genericComponent()({
5606
5619
  const VSelectionControlGroupSymbol = Symbol.for('vuetify:selection-control-group');
5607
5620
  const makeSelectionControlGroupProps = propsFactory({
5608
5621
  color: String,
5609
- disabled: Boolean,
5622
+ disabled: {
5623
+ type: Boolean,
5624
+ default: null
5625
+ },
5610
5626
  defaultsTarget: String,
5611
5627
  error: Boolean,
5612
5628
  id: String,
@@ -5830,12 +5846,12 @@ const VSelectionControl = genericComponent()({
5830
5846
  }, null), createVNode("input", mergeProps({
5831
5847
  "ref": input,
5832
5848
  "checked": model.value,
5833
- "disabled": props.disabled,
5849
+ "disabled": !!(props.readonly || props.disabled),
5834
5850
  "id": id.value,
5835
5851
  "onBlur": onBlur,
5836
5852
  "onFocus": onFocus,
5837
5853
  "onInput": onInput,
5838
- "aria-disabled": props.readonly,
5854
+ "aria-disabled": !!(props.readonly || props.disabled),
5839
5855
  "type": props.type,
5840
5856
  "value": trueValue.value,
5841
5857
  "name": props.name,
@@ -8706,7 +8722,9 @@ function blockScrollStrategy(data, props) {
8706
8722
  scrollElements.forEach((el, i) => {
8707
8723
  el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft));
8708
8724
  el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop));
8709
- el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
8725
+ if (el !== document.documentElement) {
8726
+ el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
8727
+ }
8710
8728
  el.classList.add('v-overlay-scroll-blocked');
8711
8729
  });
8712
8730
  onScopeDispose(() => {
@@ -9597,11 +9615,11 @@ const VOverlay = genericComponent()({
9597
9615
  props: mergeProps({
9598
9616
  ref: activatorRef
9599
9617
  }, activatorEvents.value, props.activatorProps)
9600
- }), isMounted.value && createVNode(Teleport, {
9618
+ }), isMounted.value && hasContent.value && createVNode(Teleport, {
9601
9619
  "disabled": !teleportTarget.value,
9602
9620
  "to": teleportTarget.value
9603
9621
  }, {
9604
- default: () => [hasContent.value && createVNode("div", mergeProps({
9622
+ default: () => [createVNode("div", mergeProps({
9605
9623
  "class": ['v-overlay', {
9606
9624
  'v-overlay--absolute': props.absolute || props.contained,
9607
9625
  'v-overlay--active': isActive.value,
@@ -10361,12 +10379,16 @@ const VTextField = genericComponent()({
10361
10379
  }]]);
10362
10380
  return createVNode(Fragment, null, [props.prefix && createVNode("span", {
10363
10381
  "class": "v-text-field__prefix"
10364
- }, [props.prefix]), createVNode("div", {
10382
+ }, [createVNode("span", {
10383
+ "class": "v-text-field__prefix__text"
10384
+ }, [props.prefix])]), createVNode("div", {
10365
10385
  "class": fieldClass,
10366
10386
  "data-no-activator": ""
10367
10387
  }, [slots.default ? createVNode(Fragment, null, [slots.default(), inputNode]) : cloneVNode(inputNode)]), props.suffix && createVNode("span", {
10368
10388
  "class": "v-text-field__suffix"
10369
- }, [props.suffix])]);
10389
+ }, [createVNode("span", {
10390
+ "class": "v-text-field__suffix__text"
10391
+ }, [props.suffix])])]);
10370
10392
  }
10371
10393
  });
10372
10394
  },
@@ -10383,6 +10405,301 @@ const VTextField = genericComponent()({
10383
10405
 
10384
10406
  // Types
10385
10407
 
10408
+ const makeVVirtualScrollItemProps = propsFactory({
10409
+ renderless: Boolean,
10410
+ ...makeComponentProps()
10411
+ }, 'VVirtualScrollItem');
10412
+ const VVirtualScrollItem = genericComponent()({
10413
+ name: 'VVirtualScrollItem',
10414
+ inheritAttrs: false,
10415
+ props: makeVVirtualScrollItemProps(),
10416
+ emits: {
10417
+ 'update:height': height => true
10418
+ },
10419
+ setup(props, _ref) {
10420
+ let {
10421
+ attrs,
10422
+ emit,
10423
+ slots
10424
+ } = _ref;
10425
+ const {
10426
+ resizeRef,
10427
+ contentRect
10428
+ } = useResizeObserver(undefined, 'border');
10429
+ watch(() => contentRect.value?.height, height => {
10430
+ if (height != null) emit('update:height', height);
10431
+ });
10432
+ useRender(() => props.renderless ? createVNode(Fragment, null, [slots.default?.({
10433
+ itemRef: resizeRef
10434
+ })]) : createVNode("div", mergeProps({
10435
+ "ref": resizeRef,
10436
+ "class": ['v-virtual-scroll__item', props.class],
10437
+ "style": props.style
10438
+ }, attrs), [slots.default?.()]));
10439
+ }
10440
+ });
10441
+
10442
+ // Composables
10443
+
10444
+ // Types
10445
+
10446
+ const UP = -1;
10447
+ const DOWN = 1;
10448
+ const makeVirtualProps = propsFactory({
10449
+ itemHeight: {
10450
+ type: [Number, String],
10451
+ default: 48
10452
+ }
10453
+ }, 'virtual');
10454
+ function useVirtual(props, items, offset) {
10455
+ const first = shallowRef(0);
10456
+ const baseItemHeight = shallowRef(props.itemHeight);
10457
+ const itemHeight = computed({
10458
+ get: () => parseInt(baseItemHeight.value ?? 0, 10),
10459
+ set(val) {
10460
+ baseItemHeight.value = val;
10461
+ }
10462
+ });
10463
+ const containerRef = ref();
10464
+ const {
10465
+ resizeRef,
10466
+ contentRect
10467
+ } = useResizeObserver();
10468
+ watchEffect(() => {
10469
+ resizeRef.value = containerRef.value;
10470
+ });
10471
+ const display = useDisplay();
10472
+ const sizeMap = new Map();
10473
+ let sizes = Array.from({
10474
+ length: items.value.length
10475
+ });
10476
+ const visibleItems = computed(() => {
10477
+ const height = (!contentRect.value || containerRef.value === document.documentElement ? display.height.value : contentRect.value.height) - (offset?.value ?? 0);
10478
+ return Math.ceil(height / itemHeight.value * 1.7 + 1);
10479
+ });
10480
+ function handleItemResize(index, height) {
10481
+ itemHeight.value = Math.max(itemHeight.value, height);
10482
+ sizes[index] = height;
10483
+ sizeMap.set(items.value[index], height);
10484
+ }
10485
+ function calculateOffset(index) {
10486
+ return sizes.slice(0, index).reduce((acc, val) => acc + (val || itemHeight.value), 0);
10487
+ }
10488
+ function calculateMidPointIndex(scrollTop) {
10489
+ const end = items.value.length;
10490
+ let middle = 0;
10491
+ let middleOffset = 0;
10492
+ while (middleOffset < scrollTop && middle < end) {
10493
+ middleOffset += sizes[middle++] || itemHeight.value;
10494
+ }
10495
+ return middle - 1;
10496
+ }
10497
+ let lastScrollTop = 0;
10498
+ function handleScroll() {
10499
+ if (!containerRef.value || !contentRect.value) return;
10500
+ const height = contentRect.value.height - 56;
10501
+ const scrollTop = containerRef.value.scrollTop;
10502
+ const direction = scrollTop < lastScrollTop ? UP : DOWN;
10503
+ const midPointIndex = calculateMidPointIndex(scrollTop + height / 2);
10504
+ const buffer = Math.round(visibleItems.value / 3);
10505
+ const firstIndex = midPointIndex - buffer;
10506
+ const lastIndex = first.value + buffer * 2 - 1;
10507
+ if (direction === UP && midPointIndex <= lastIndex) {
10508
+ first.value = clamp(firstIndex, 0, items.value.length);
10509
+ } else if (direction === DOWN && midPointIndex >= lastIndex) {
10510
+ first.value = clamp(firstIndex, 0, items.value.length - visibleItems.value);
10511
+ }
10512
+ lastScrollTop = scrollTop;
10513
+ }
10514
+ function scrollToIndex(index) {
10515
+ if (!containerRef.value) return;
10516
+ const offset = calculateOffset(index);
10517
+ containerRef.value.scrollTop = offset;
10518
+ }
10519
+ const last = computed(() => Math.min(items.value.length, first.value + visibleItems.value));
10520
+ const computedItems = computed(() => {
10521
+ return items.value.slice(first.value, last.value).map((item, index) => ({
10522
+ raw: item,
10523
+ index: index + first.value
10524
+ }));
10525
+ });
10526
+ const paddingTop = computed(() => calculateOffset(first.value));
10527
+ const paddingBottom = computed(() => calculateOffset(items.value.length) - calculateOffset(last.value));
10528
+ watch(() => items.value.length, () => {
10529
+ sizes = createRange(items.value.length).map(() => itemHeight.value);
10530
+ sizeMap.forEach((height, item) => {
10531
+ const index = items.value.indexOf(item);
10532
+ if (index === -1) {
10533
+ sizeMap.delete(item);
10534
+ } else {
10535
+ sizes[index] = height;
10536
+ }
10537
+ });
10538
+ });
10539
+ return {
10540
+ containerRef,
10541
+ computedItems,
10542
+ itemHeight,
10543
+ paddingTop,
10544
+ paddingBottom,
10545
+ scrollToIndex,
10546
+ handleScroll,
10547
+ handleItemResize
10548
+ };
10549
+ }
10550
+
10551
+ // Types
10552
+
10553
+ const makeVVirtualScrollProps = propsFactory({
10554
+ items: {
10555
+ type: Array,
10556
+ default: () => []
10557
+ },
10558
+ renderless: Boolean,
10559
+ ...makeVirtualProps(),
10560
+ ...makeComponentProps(),
10561
+ ...makeDimensionProps()
10562
+ }, 'VVirtualScroll');
10563
+ const VVirtualScroll = genericComponent()({
10564
+ name: 'VVirtualScroll',
10565
+ props: makeVVirtualScrollProps(),
10566
+ setup(props, _ref) {
10567
+ let {
10568
+ slots
10569
+ } = _ref;
10570
+ const vm = getCurrentInstance('VVirtualScroll');
10571
+ const {
10572
+ dimensionStyles
10573
+ } = useDimension(props);
10574
+ const {
10575
+ containerRef,
10576
+ handleScroll,
10577
+ handleItemResize,
10578
+ scrollToIndex,
10579
+ paddingTop,
10580
+ paddingBottom,
10581
+ computedItems
10582
+ } = useVirtual(props, toRef(props, 'items'));
10583
+ useToggleScope(() => props.renderless, () => {
10584
+ onMounted(() => {
10585
+ containerRef.value = getScrollParent(vm.vnode.el, true);
10586
+ containerRef.value?.addEventListener('scroll', handleScroll);
10587
+ });
10588
+ onScopeDispose(() => {
10589
+ containerRef.value?.removeEventListener('scroll', handleScroll);
10590
+ });
10591
+ });
10592
+ useRender(() => {
10593
+ const children = computedItems.value.map(item => createVNode(VVirtualScrollItem, {
10594
+ "key": item.index,
10595
+ "renderless": props.renderless,
10596
+ "onUpdate:height": height => handleItemResize(item.index, height)
10597
+ }, {
10598
+ default: slotProps => slots.default?.({
10599
+ item: item.raw,
10600
+ index: item.index,
10601
+ ...slotProps
10602
+ })
10603
+ }));
10604
+ return props.renderless ? createVNode(Fragment, null, [createVNode("div", {
10605
+ "class": "v-virtual-scroll__spacer",
10606
+ "style": {
10607
+ paddingTop: convertToUnit(paddingTop.value)
10608
+ }
10609
+ }, null), children, createVNode("div", {
10610
+ "class": "v-virtual-scroll__spacer",
10611
+ "style": {
10612
+ paddingBottom: convertToUnit(paddingBottom.value)
10613
+ }
10614
+ }, null)]) : createVNode("div", {
10615
+ "ref": containerRef,
10616
+ "class": ['v-virtual-scroll', props.class],
10617
+ "onScroll": handleScroll,
10618
+ "style": [dimensionStyles.value, props.style]
10619
+ }, [createVNode("div", {
10620
+ "class": "v-virtual-scroll__container",
10621
+ "style": {
10622
+ paddingTop: convertToUnit(paddingTop.value),
10623
+ paddingBottom: convertToUnit(paddingBottom.value)
10624
+ }
10625
+ }, [children])]);
10626
+ });
10627
+ return {
10628
+ scrollToIndex
10629
+ };
10630
+ }
10631
+ });
10632
+
10633
+ // Utilities
10634
+
10635
+ // Types
10636
+
10637
+ function useScrolling(listRef, textFieldRef) {
10638
+ const isScrolling = shallowRef(false);
10639
+ let scrollTimeout;
10640
+ function onListScroll(e) {
10641
+ cancelAnimationFrame(scrollTimeout);
10642
+ isScrolling.value = true;
10643
+ scrollTimeout = requestAnimationFrame(() => {
10644
+ scrollTimeout = requestAnimationFrame(() => {
10645
+ isScrolling.value = false;
10646
+ });
10647
+ });
10648
+ }
10649
+ async function finishScrolling() {
10650
+ await new Promise(resolve => requestAnimationFrame(resolve));
10651
+ await new Promise(resolve => requestAnimationFrame(resolve));
10652
+ await new Promise(resolve => requestAnimationFrame(resolve));
10653
+ await new Promise(resolve => {
10654
+ if (isScrolling.value) {
10655
+ const stop = watch(isScrolling, () => {
10656
+ stop();
10657
+ resolve();
10658
+ });
10659
+ } else resolve();
10660
+ });
10661
+ }
10662
+ async function onListKeydown(e) {
10663
+ if (e.key === 'Tab') {
10664
+ textFieldRef.value?.focus();
10665
+ }
10666
+ if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return;
10667
+ const el = listRef.value?.$el;
10668
+ if (!el) return;
10669
+ if (e.key === 'Home' || e.key === 'End') {
10670
+ el.scrollTo({
10671
+ top: e.key === 'Home' ? 0 : el.scrollHeight,
10672
+ behavior: 'smooth'
10673
+ });
10674
+ }
10675
+ await finishScrolling();
10676
+ const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)');
10677
+ if (e.key === 'PageDown' || e.key === 'Home') {
10678
+ const top = el.getBoundingClientRect().top;
10679
+ for (const child of children) {
10680
+ if (child.getBoundingClientRect().top >= top) {
10681
+ child.focus();
10682
+ break;
10683
+ }
10684
+ }
10685
+ } else {
10686
+ const bottom = el.getBoundingClientRect().bottom;
10687
+ for (const child of [...children].reverse()) {
10688
+ if (child.getBoundingClientRect().bottom <= bottom) {
10689
+ child.focus();
10690
+ break;
10691
+ }
10692
+ }
10693
+ }
10694
+ }
10695
+ return {
10696
+ onListScroll,
10697
+ onListKeydown
10698
+ };
10699
+ }
10700
+
10701
+ // Types
10702
+
10386
10703
  const makeSelectProps = propsFactory({
10387
10704
  chips: Boolean,
10388
10705
  closableChips: Boolean,
@@ -10474,6 +10791,10 @@ const VSelect = genericComponent()({
10474
10791
  });
10475
10792
  const menuDisabled = computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
10476
10793
  const listRef = ref();
10794
+ const {
10795
+ onListScroll,
10796
+ onListKeydown
10797
+ } = useScrolling(listRef, vTextFieldRef);
10477
10798
  function onClear(e) {
10478
10799
  if (props.openOnClear) {
10479
10800
  menu.value = true;
@@ -10520,11 +10841,6 @@ const VSelect = genericComponent()({
10520
10841
  model.value = [item];
10521
10842
  }
10522
10843
  }
10523
- function onListKeydown(e) {
10524
- if (e.key === 'Tab') {
10525
- vTextFieldRef.value?.focus();
10526
- }
10527
- }
10528
10844
  function select(item) {
10529
10845
  if (props.multiple) {
10530
10846
  const index = selected.value.findIndex(selection => props.valueComparator(selection, item.value));
@@ -10607,34 +10923,46 @@ const VSelect = genericComponent()({
10607
10923
  "onMousedown": e => e.preventDefault(),
10608
10924
  "onKeydown": onListKeydown,
10609
10925
  "onFocusin": onFocusin,
10926
+ "onScrollPassive": onListScroll,
10610
10927
  "tabindex": "-1"
10611
10928
  }, {
10612
10929
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
10613
10930
  "title": t(props.noDataText)
10614
- }, null)), displayItems.value.map((item, index) => {
10615
- const itemProps = mergeProps(item.props, {
10616
- key: index,
10617
- onClick: () => select(item)
10618
- });
10619
- return slots.item?.({
10620
- item,
10621
- index,
10622
- props: itemProps
10623
- }) ?? createVNode(VListItem, itemProps, {
10624
- prepend: _ref2 => {
10625
- let {
10626
- isSelected
10627
- } = _ref2;
10628
- return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
10629
- "key": item.value,
10630
- "modelValue": isSelected,
10631
- "ripple": false,
10632
- "tabindex": "-1"
10633
- }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
10634
- "icon": item.props.prependIcon
10635
- }, null)]);
10636
- }
10637
- });
10931
+ }, null)), createVNode(VVirtualScroll, {
10932
+ "renderless": true,
10933
+ "items": displayItems.value
10934
+ }, {
10935
+ default: _ref2 => {
10936
+ let {
10937
+ item,
10938
+ index,
10939
+ itemRef
10940
+ } = _ref2;
10941
+ const itemProps = mergeProps(item.props, {
10942
+ ref: itemRef,
10943
+ key: index,
10944
+ onClick: () => select(item)
10945
+ });
10946
+ return slots.item?.({
10947
+ item,
10948
+ index,
10949
+ props: itemProps
10950
+ }) ?? createVNode(VListItem, itemProps, {
10951
+ prepend: _ref3 => {
10952
+ let {
10953
+ isSelected
10954
+ } = _ref3;
10955
+ return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
10956
+ "key": item.value,
10957
+ "modelValue": isSelected,
10958
+ "ripple": false,
10959
+ "tabindex": "-1"
10960
+ }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
10961
+ "icon": item.props.prependIcon
10962
+ }, null)]);
10963
+ }
10964
+ });
10965
+ }
10638
10966
  }), slots['append-item']?.()]
10639
10967
  })]
10640
10968
  }), selections.value.map((item, index) => {
@@ -10772,14 +11100,13 @@ function filterItems(items, query, options) {
10772
11100
  return array;
10773
11101
  }
10774
11102
  function useFilter(props, items, query, options) {
10775
- const strQuery = computed(() => typeof query?.value !== 'string' && typeof query?.value !== 'number' ? '' : String(query.value));
10776
11103
  const filteredItems = ref([]);
10777
11104
  const filteredMatches = ref(new Map());
10778
11105
  const transformedItems = computed(() => options?.transform ? unref(items).map(options?.transform) : unref(items));
10779
11106
  watchEffect(() => {
10780
- filteredItems.value = [];
10781
- filteredMatches.value = new Map();
10782
- const results = filterItems(transformedItems.value, strQuery.value, {
11107
+ const _query = typeof query === 'function' ? query() : unref(query);
11108
+ const strQuery = typeof _query !== 'string' && typeof _query !== 'number' ? '' : String(_query);
11109
+ const results = filterItems(transformedItems.value, strQuery, {
10783
11110
  customKeyFilter: props.customKeyFilter,
10784
11111
  default: props.customFilter,
10785
11112
  filterKeys: props.filterKeys,
@@ -10787,15 +11114,19 @@ function useFilter(props, items, query, options) {
10787
11114
  noFilter: props.noFilter
10788
11115
  });
10789
11116
  const originalItems = unref(items);
11117
+ const _filteredItems = [];
11118
+ const _filteredMatches = new Map();
10790
11119
  results.forEach(_ref => {
10791
11120
  let {
10792
11121
  index,
10793
11122
  matches
10794
11123
  } = _ref;
10795
11124
  const item = originalItems[index];
10796
- filteredItems.value.push(item);
10797
- filteredMatches.value.set(item.value, matches);
11125
+ _filteredItems.push(item);
11126
+ _filteredMatches.set(item.value, matches);
10798
11127
  });
11128
+ filteredItems.value = _filteredItems;
11129
+ filteredMatches.value = _filteredMatches;
10799
11130
  });
10800
11131
  function getMatches(item) {
10801
11132
  return filteredMatches.value.get(item.value);
@@ -10885,7 +11216,7 @@ const VAutocomplete = genericComponent()({
10885
11216
  const {
10886
11217
  filteredItems,
10887
11218
  getMatches
10888
- } = useFilter(props, items, computed(() => isPristine.value ? undefined : search.value));
11219
+ } = useFilter(props, items, () => isPristine.value ? '' : search.value);
10889
11220
  const selections = computed(() => {
10890
11221
  return model.value.map(v => {
10891
11222
  return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
@@ -10905,6 +11236,10 @@ const VAutocomplete = genericComponent()({
10905
11236
  });
10906
11237
  const menuDisabled = computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
10907
11238
  const listRef = ref();
11239
+ const {
11240
+ onListScroll,
11241
+ onListKeydown
11242
+ } = useScrolling(listRef, vTextFieldRef);
10908
11243
  function onClear(e) {
10909
11244
  if (props.openOnClear) {
10910
11245
  menu.value = true;
@@ -10978,11 +11313,6 @@ const VAutocomplete = genericComponent()({
10978
11313
  }
10979
11314
  }
10980
11315
  }
10981
- function onListKeydown(e) {
10982
- if (e.key === 'Tab') {
10983
- vTextFieldRef.value?.focus();
10984
- }
10985
- }
10986
11316
  function onInput(e) {
10987
11317
  search.value = e.target.value;
10988
11318
  }
@@ -11101,38 +11431,50 @@ const VAutocomplete = genericComponent()({
11101
11431
  "onKeydown": onListKeydown,
11102
11432
  "onFocusin": onFocusin,
11103
11433
  "onFocusout": onFocusout,
11434
+ "onScrollPassive": onListScroll,
11104
11435
  "tabindex": "-1"
11105
11436
  }, {
11106
11437
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
11107
11438
  "title": t(props.noDataText)
11108
- }, null)), displayItems.value.map((item, index) => {
11109
- const itemProps = mergeProps(item.props, {
11110
- key: index,
11111
- active: highlightFirst.value && index === 0 ? true : undefined,
11112
- onClick: () => select(item)
11113
- });
11114
- return slots.item?.({
11115
- item,
11116
- index,
11117
- props: itemProps
11118
- }) ?? createVNode(VListItem, itemProps, {
11119
- prepend: _ref3 => {
11120
- let {
11121
- isSelected
11122
- } = _ref3;
11123
- return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
11124
- "key": item.value,
11125
- "modelValue": isSelected,
11126
- "ripple": false,
11127
- "tabindex": "-1"
11128
- }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
11129
- "icon": item.props.prependIcon
11130
- }, null)]);
11131
- },
11132
- title: () => {
11133
- return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
11134
- }
11135
- });
11439
+ }, null)), createVNode(VVirtualScroll, {
11440
+ "renderless": true,
11441
+ "items": displayItems.value
11442
+ }, {
11443
+ default: _ref3 => {
11444
+ let {
11445
+ item,
11446
+ index,
11447
+ itemRef
11448
+ } = _ref3;
11449
+ const itemProps = mergeProps(item.props, {
11450
+ ref: itemRef,
11451
+ key: index,
11452
+ active: highlightFirst.value && index === 0 ? true : undefined,
11453
+ onClick: () => select(item)
11454
+ });
11455
+ return slots.item?.({
11456
+ item,
11457
+ index,
11458
+ props: itemProps
11459
+ }) ?? createVNode(VListItem, itemProps, {
11460
+ prepend: _ref4 => {
11461
+ let {
11462
+ isSelected
11463
+ } = _ref4;
11464
+ return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
11465
+ "key": item.value,
11466
+ "modelValue": isSelected,
11467
+ "ripple": false,
11468
+ "tabindex": "-1"
11469
+ }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
11470
+ "icon": item.props.prependIcon
11471
+ }, null)]);
11472
+ },
11473
+ title: () => {
11474
+ return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
11475
+ }
11476
+ });
11477
+ }
11136
11478
  }), slots['append-item']?.()]
11137
11479
  })]
11138
11480
  }), selections.value.map((item, index) => {
@@ -12336,64 +12678,65 @@ const VCarousel = genericComponent()({
12336
12678
  window.clearTimeout(slideTimeout);
12337
12679
  window.requestAnimationFrame(startTimeout);
12338
12680
  }
12339
- useRender(() => createVNode(VWindow, {
12340
- "ref": windowRef,
12341
- "modelValue": model.value,
12342
- "onUpdate:modelValue": $event => model.value = $event,
12343
- "class": ['v-carousel', {
12344
- 'v-carousel--hide-delimiter-background': props.hideDelimiterBackground,
12345
- 'v-carousel--vertical-delimiters': props.verticalDelimiters
12346
- }, props.class],
12347
- "style": [{
12348
- height: convertToUnit(props.height)
12349
- }, props.style],
12350
- "continuous": true,
12351
- "mandatory": "force",
12352
- "showArrows": props.showArrows
12353
- }, {
12354
- default: slots.default,
12355
- additional: _ref2 => {
12356
- let {
12357
- group
12358
- } = _ref2;
12359
- return createVNode(Fragment, null, [!props.hideDelimiters && createVNode("div", {
12360
- "class": "v-carousel__controls",
12361
- "style": {
12362
- left: props.verticalDelimiters === 'left' && props.verticalDelimiters ? 0 : 'auto',
12363
- right: props.verticalDelimiters === 'right' ? 0 : 'auto'
12364
- }
12365
- }, [group.items.value.length > 0 && createVNode(VDefaultsProvider, {
12366
- "defaults": {
12367
- VBtn: {
12368
- color: props.color,
12369
- icon: props.delimiterIcon,
12370
- size: 'x-small',
12371
- variant: 'text'
12681
+ useRender(() => {
12682
+ const [windowProps] = VWindow.filterProps(props);
12683
+ return createVNode(VWindow, mergeProps({
12684
+ "ref": windowRef
12685
+ }, windowProps, {
12686
+ "modelValue": model.value,
12687
+ "onUpdate:modelValue": $event => model.value = $event,
12688
+ "class": ['v-carousel', {
12689
+ 'v-carousel--hide-delimiter-background': props.hideDelimiterBackground,
12690
+ 'v-carousel--vertical-delimiters': props.verticalDelimiters
12691
+ }, props.class],
12692
+ "style": [{
12693
+ height: convertToUnit(props.height)
12694
+ }, props.style]
12695
+ }), {
12696
+ default: slots.default,
12697
+ additional: _ref2 => {
12698
+ let {
12699
+ group
12700
+ } = _ref2;
12701
+ return createVNode(Fragment, null, [!props.hideDelimiters && createVNode("div", {
12702
+ "class": "v-carousel__controls",
12703
+ "style": {
12704
+ left: props.verticalDelimiters === 'left' && props.verticalDelimiters ? 0 : 'auto',
12705
+ right: props.verticalDelimiters === 'right' ? 0 : 'auto'
12372
12706
  }
12373
- },
12374
- "scoped": true
12375
- }, {
12376
- default: () => [group.items.value.map((item, index) => {
12377
- const props = {
12378
- id: `carousel-item-${item.id}`,
12379
- 'aria-label': t('$vuetify.carousel.ariaLabel.delimiter', index + 1, group.items.value.length),
12380
- class: [group.isSelected(item.id) && 'v-btn--active'],
12381
- onClick: () => group.select(item.id, true)
12382
- };
12383
- return slots.item ? slots.item({
12384
- props,
12385
- item
12386
- }) : createVNode(VBtn, mergeProps(item, props), null);
12387
- })]
12388
- })]), props.progress && createVNode(VProgressLinear, {
12389
- "class": "v-carousel__progress",
12390
- "color": typeof props.progress === 'string' ? props.progress : undefined,
12391
- "modelValue": (group.getItemIndex(model.value) + 1) / group.items.value.length * 100
12392
- }, null)]);
12393
- },
12394
- prev: slots.prev,
12395
- next: slots.next
12396
- }));
12707
+ }, [group.items.value.length > 0 && createVNode(VDefaultsProvider, {
12708
+ "defaults": {
12709
+ VBtn: {
12710
+ color: props.color,
12711
+ icon: props.delimiterIcon,
12712
+ size: 'x-small',
12713
+ variant: 'text'
12714
+ }
12715
+ },
12716
+ "scoped": true
12717
+ }, {
12718
+ default: () => [group.items.value.map((item, index) => {
12719
+ const props = {
12720
+ id: `carousel-item-${item.id}`,
12721
+ 'aria-label': t('$vuetify.carousel.ariaLabel.delimiter', index + 1, group.items.value.length),
12722
+ class: [group.isSelected(item.id) && 'v-btn--active'],
12723
+ onClick: () => group.select(item.id, true)
12724
+ };
12725
+ return slots.item ? slots.item({
12726
+ props,
12727
+ item
12728
+ }) : createVNode(VBtn, mergeProps(item, props), null);
12729
+ })]
12730
+ })]), props.progress && createVNode(VProgressLinear, {
12731
+ "class": "v-carousel__progress",
12732
+ "color": typeof props.progress === 'string' ? props.progress : undefined,
12733
+ "modelValue": (group.getItemIndex(model.value) + 1) / group.items.value.length * 100
12734
+ }, null)]);
12735
+ },
12736
+ prev: slots.prev,
12737
+ next: slots.next
12738
+ });
12739
+ });
12397
12740
  return {};
12398
12741
  }
12399
12742
  });
@@ -14426,7 +14769,7 @@ const VCombobox = genericComponent()({
14426
14769
  const {
14427
14770
  filteredItems,
14428
14771
  getMatches
14429
- } = useFilter(props, items, computed(() => isPristine.value ? undefined : search.value));
14772
+ } = useFilter(props, items, () => isPristine.value ? '' : search.value);
14430
14773
  const selections = computed(() => {
14431
14774
  return model.value.map(v => {
14432
14775
  return items.value.find(item => props.valueComparator(item.value, v.value)) || v;
@@ -14446,6 +14789,10 @@ const VCombobox = genericComponent()({
14446
14789
  });
14447
14790
  const menuDisabled = computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
14448
14791
  const listRef = ref();
14792
+ const {
14793
+ onListScroll,
14794
+ onListKeydown
14795
+ } = useScrolling(listRef, vTextFieldRef);
14449
14796
  function onClear(e) {
14450
14797
  cleared = true;
14451
14798
  if (props.openOnClear) {
@@ -14523,11 +14870,6 @@ const VCombobox = genericComponent()({
14523
14870
  search.value = '';
14524
14871
  }
14525
14872
  }
14526
- function onListKeydown(e) {
14527
- if (e.key === 'Tab') {
14528
- vTextFieldRef.value?.focus();
14529
- }
14530
- }
14531
14873
  function onAfterLeave() {
14532
14874
  if (isFocused.value) {
14533
14875
  isPristine.value = true;
@@ -14638,38 +14980,50 @@ const VCombobox = genericComponent()({
14638
14980
  "onKeydown": onListKeydown,
14639
14981
  "onFocusin": onFocusin,
14640
14982
  "onFocusout": onFocusout,
14983
+ "onScrollPassive": onListScroll,
14641
14984
  "tabindex": "-1"
14642
14985
  }, {
14643
14986
  default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
14644
14987
  "title": t(props.noDataText)
14645
- }, null)), displayItems.value.map((item, index) => {
14646
- const itemProps = mergeProps(item.props, {
14647
- key: index,
14648
- active: highlightFirst.value && index === 0 ? true : undefined,
14649
- onClick: () => select(item)
14650
- });
14651
- return slots.item?.({
14652
- item,
14653
- index,
14654
- props: itemProps
14655
- }) ?? createVNode(VListItem, itemProps, {
14656
- prepend: _ref3 => {
14657
- let {
14658
- isSelected
14659
- } = _ref3;
14660
- return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
14661
- "key": item.value,
14662
- "modelValue": isSelected,
14663
- "ripple": false,
14664
- "tabindex": "-1"
14665
- }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
14666
- "icon": item.props.prependIcon
14667
- }, null)]);
14668
- },
14669
- title: () => {
14670
- return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
14671
- }
14672
- });
14988
+ }, null)), createVNode(VVirtualScroll, {
14989
+ "renderless": true,
14990
+ "items": displayItems.value
14991
+ }, {
14992
+ default: _ref3 => {
14993
+ let {
14994
+ item,
14995
+ index,
14996
+ itemRef
14997
+ } = _ref3;
14998
+ const itemProps = mergeProps(item.props, {
14999
+ ref: itemRef,
15000
+ key: index,
15001
+ active: highlightFirst.value && index === 0 ? true : undefined,
15002
+ onClick: () => select(item)
15003
+ });
15004
+ return slots.item?.({
15005
+ item,
15006
+ index,
15007
+ props: itemProps
15008
+ }) ?? createVNode(VListItem, itemProps, {
15009
+ prepend: _ref4 => {
15010
+ let {
15011
+ isSelected
15012
+ } = _ref4;
15013
+ return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
15014
+ "key": item.value,
15015
+ "modelValue": isSelected,
15016
+ "ripple": false,
15017
+ "tabindex": "-1"
15018
+ }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
15019
+ "icon": item.props.prependIcon
15020
+ }, null)]);
15021
+ },
15022
+ title: () => {
15023
+ return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
15024
+ }
15025
+ });
15026
+ }
14673
15027
  }), slots['append-item']?.()]
14674
15028
  })]
14675
15029
  }), selections.value.map((item, index) => {
@@ -19013,215 +19367,6 @@ const VValidation = genericComponent()({
19013
19367
  }
19014
19368
  });
19015
19369
 
19016
- const makeVVirtualScrollItemProps = propsFactory({
19017
- dynamicHeight: Boolean,
19018
- renderless: Boolean,
19019
- ...makeComponentProps()
19020
- }, 'VVirtualScrollItem');
19021
- const VVirtualScrollItem = genericComponent()({
19022
- name: 'VVirtualScrollItem',
19023
- props: makeVVirtualScrollItemProps(),
19024
- emits: {
19025
- 'update:height': height => true
19026
- },
19027
- setup(props, _ref) {
19028
- let {
19029
- emit,
19030
- slots
19031
- } = _ref;
19032
- const {
19033
- resizeRef,
19034
- contentRect
19035
- } = useResizeObserver();
19036
- useToggleScope(() => props.dynamicHeight, () => {
19037
- watch(() => contentRect.value?.height, height => {
19038
- if (height != null) emit('update:height', height);
19039
- });
19040
- });
19041
- function updateHeight() {
19042
- if (props.dynamicHeight && contentRect.value) {
19043
- emit('update:height', contentRect.value.height);
19044
- }
19045
- }
19046
- onUpdated(updateHeight);
19047
- useRender(() => props.renderless ? createVNode(Fragment, null, [slots.default?.({
19048
- props: {
19049
- ref: props.dynamicHeight ? resizeRef : undefined
19050
- }
19051
- })]) : createVNode("div", {
19052
- "ref": props.dynamicHeight ? resizeRef : undefined,
19053
- "class": ['v-virtual-scroll__item', props.class],
19054
- "style": props.style
19055
- }, [slots.default?.()]));
19056
- }
19057
- });
19058
-
19059
- // Composables
19060
-
19061
- // Types
19062
-
19063
- const UP = -1;
19064
- const DOWN = 1;
19065
- const makeVirtualProps = propsFactory({
19066
- itemHeight: [Number, String]
19067
- }, 'virtual');
19068
- function useVirtual(props, items, offset) {
19069
- const first = shallowRef(0);
19070
- const baseItemHeight = shallowRef(props.itemHeight);
19071
- const itemHeight = computed({
19072
- get: () => parseInt(baseItemHeight.value ?? 0, 10),
19073
- set(val) {
19074
- baseItemHeight.value = val;
19075
- }
19076
- });
19077
- const containerRef = ref();
19078
- const {
19079
- resizeRef,
19080
- contentRect
19081
- } = useResizeObserver();
19082
- watchEffect(() => {
19083
- resizeRef.value = containerRef.value;
19084
- });
19085
- const display = useDisplay();
19086
- const sizeMap = new Map();
19087
- let sizes = createRange(items.value.length).map(() => itemHeight.value);
19088
- const visibleItems = computed(() => {
19089
- const height = (contentRect.value?.height ?? display.height.value) - (offset?.value ?? 0);
19090
- return itemHeight.value ? Math.max(12, Math.ceil(height / itemHeight.value * 1.7 + 1)) : 12;
19091
- });
19092
- function handleItemResize(index, height) {
19093
- itemHeight.value = Math.max(itemHeight.value, height);
19094
- sizes[index] = height;
19095
- sizeMap.set(items.value[index], height);
19096
- }
19097
- function calculateOffset(index) {
19098
- return sizes.slice(0, index).reduce((curr, value) => curr + (value || itemHeight.value), 0);
19099
- }
19100
- function calculateMidPointIndex(scrollTop) {
19101
- const end = items.value.length;
19102
- let middle = 0;
19103
- let middleOffset = 0;
19104
- while (middleOffset < scrollTop && middle < end) {
19105
- middleOffset += sizes[middle++] || itemHeight.value;
19106
- }
19107
- return middle - 1;
19108
- }
19109
- let lastScrollTop = 0;
19110
- function handleScroll() {
19111
- if (!containerRef.value || !contentRect.value) return;
19112
- const height = contentRect.value.height - 56;
19113
- const scrollTop = containerRef.value.scrollTop;
19114
- const direction = scrollTop < lastScrollTop ? UP : DOWN;
19115
- const midPointIndex = calculateMidPointIndex(scrollTop + height / 2);
19116
- const buffer = Math.round(visibleItems.value / 3);
19117
- const firstIndex = midPointIndex - buffer;
19118
- const lastIndex = first.value + buffer * 2 - 1;
19119
- if (direction === UP && midPointIndex <= lastIndex) {
19120
- first.value = clamp(firstIndex, 0, items.value.length);
19121
- } else if (direction === DOWN && midPointIndex >= lastIndex) {
19122
- first.value = clamp(firstIndex, 0, items.value.length - visibleItems.value);
19123
- }
19124
- lastScrollTop = scrollTop;
19125
- }
19126
- function scrollToIndex(index) {
19127
- if (!containerRef.value) return;
19128
- const offset = calculateOffset(index);
19129
- containerRef.value.scrollTop = offset;
19130
- }
19131
- const allItems = computed(() => items.value.map((item, index) => ({
19132
- raw: item,
19133
- index
19134
- })));
19135
- const last = computed(() => Math.min(items.value.length, first.value + visibleItems.value));
19136
- const computedItems = computed(() => allItems.value.slice(first.value, last.value));
19137
- const paddingTop = computed(() => calculateOffset(first.value));
19138
- const paddingBottom = computed(() => calculateOffset(items.value.length) - calculateOffset(last.value));
19139
- onMounted(() => {
19140
- if (!itemHeight.value) {
19141
- // If itemHeight prop is not set, then calculate an estimated height from the average of inital items
19142
- itemHeight.value = sizes.slice(first.value, last.value).reduce((curr, height) => curr + height, 0) / visibleItems.value;
19143
- }
19144
- });
19145
- watch(() => items.value.length, () => {
19146
- sizes = createRange(items.value.length).map(() => itemHeight.value);
19147
- sizeMap.forEach((height, item) => {
19148
- const index = items.value.indexOf(item);
19149
- if (index === -1) {
19150
- sizeMap.delete(item);
19151
- } else {
19152
- sizes[index] = height;
19153
- }
19154
- });
19155
- });
19156
- return {
19157
- containerRef,
19158
- computedItems,
19159
- itemHeight,
19160
- paddingTop,
19161
- paddingBottom,
19162
- scrollToIndex,
19163
- handleScroll,
19164
- handleItemResize
19165
- };
19166
- }
19167
-
19168
- // Types
19169
-
19170
- const makeVVirtualScrollProps = propsFactory({
19171
- items: {
19172
- type: Array,
19173
- default: () => []
19174
- },
19175
- ...makeVirtualProps(),
19176
- ...makeComponentProps(),
19177
- ...makeDimensionProps()
19178
- }, 'VVirtualScroll');
19179
- const VVirtualScroll = genericComponent()({
19180
- name: 'VVirtualScroll',
19181
- props: makeVVirtualScrollProps(),
19182
- setup(props, _ref) {
19183
- let {
19184
- slots
19185
- } = _ref;
19186
- const {
19187
- dimensionStyles
19188
- } = useDimension(props);
19189
- const {
19190
- containerRef,
19191
- handleScroll,
19192
- handleItemResize,
19193
- scrollToIndex,
19194
- paddingTop,
19195
- paddingBottom,
19196
- computedItems
19197
- } = useVirtual(props, toRef(props, 'items'));
19198
- useRender(() => createVNode("div", {
19199
- "ref": containerRef,
19200
- "class": ['v-virtual-scroll', props.class],
19201
- "onScroll": handleScroll,
19202
- "style": [dimensionStyles.value, props.style]
19203
- }, [createVNode("div", {
19204
- "class": "v-virtual-scroll__container",
19205
- "style": {
19206
- paddingTop: convertToUnit(paddingTop.value),
19207
- paddingBottom: convertToUnit(paddingBottom.value)
19208
- }
19209
- }, [computedItems.value.map(item => createVNode(VVirtualScrollItem, {
19210
- "key": item.index,
19211
- "dynamicHeight": !props.itemHeight,
19212
- "onUpdate:height": height => handleItemResize(item.index, height)
19213
- }, {
19214
- default: () => [slots.default?.({
19215
- item: item.raw,
19216
- index: item.index
19217
- })]
19218
- }))])]));
19219
- return {
19220
- scrollToIndex
19221
- };
19222
- }
19223
- });
19224
-
19225
19370
  // Types
19226
19371
 
19227
19372
  const makeVBottomSheetProps = propsFactory({
@@ -20340,7 +20485,11 @@ function createHeaders(props, options) {
20340
20485
  column,
20341
20486
  row
20342
20487
  } = _ref4;
20343
- const key = column.key;
20488
+ let key = column.key;
20489
+ if (key == null) {
20490
+ consoleWarn('The header key value must not be null or undefined');
20491
+ key = '';
20492
+ }
20344
20493
  for (let i = row; i <= row + (column.rowspan ?? 1) - 1; i++) {
20345
20494
  fixedRows[i].push({
20346
20495
  ...column,
@@ -21205,19 +21354,21 @@ const VDataTableVirtual = genericComponent()({
21205
21354
  ...slots,
21206
21355
  item: itemSlotProps => createVNode(VVirtualScrollItem, {
21207
21356
  "key": itemSlotProps.item.index,
21208
- "dynamicHeight": true,
21209
21357
  "renderless": true,
21210
21358
  "onUpdate:height": height => handleItemResize(itemSlotProps.item.index, height)
21211
21359
  }, {
21212
- default: slotProps => slots.item?.({
21213
- ...itemSlotProps,
21214
- props: {
21215
- ...itemSlotProps.props,
21216
- ...slotProps?.props
21217
- }
21218
- }) ?? createVNode(VDataTableRow, mergeProps(itemSlotProps.props, slotProps?.props, {
21219
- "key": itemSlotProps.item.index
21220
- }), slots)
21360
+ default: _ref2 => {
21361
+ let {
21362
+ itemRef
21363
+ } = _ref2;
21364
+ return slots.item?.({
21365
+ ...itemSlotProps,
21366
+ itemRef
21367
+ }) ?? createVNode(VDataTableRow, mergeProps(itemSlotProps.props, {
21368
+ "ref": itemRef,
21369
+ "key": itemSlotProps.item.index
21370
+ }), slots);
21371
+ }
21221
21372
  })
21222
21373
  }), createVNode("tr", {
21223
21374
  "style": {
@@ -23447,7 +23598,7 @@ function createVuetify$1() {
23447
23598
  date
23448
23599
  };
23449
23600
  }
23450
- const version$1 = "3.3.6";
23601
+ const version$1 = "3.3.8";
23451
23602
  createVuetify$1.version = version$1;
23452
23603
 
23453
23604
  // Vue's inject() can only be used in setup
@@ -23461,7 +23612,7 @@ function inject(key) {
23461
23612
 
23462
23613
  /* eslint-disable local-rules/sort-imports */
23463
23614
 
23464
- const version = "3.3.6";
23615
+ const version = "3.3.8";
23465
23616
 
23466
23617
  /* eslint-disable local-rules/sort-imports */
23467
23618