@vuetify/nightly 3.2.0-dev-20230405.0 → 3.2.0-dev-20230415.0

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 (110) hide show
  1. package/CHANGELOG.md +3 -2
  2. package/dist/json/attributes.json +24 -8
  3. package/dist/json/importMap-labs.json +0 -4
  4. package/dist/json/importMap.json +56 -52
  5. package/dist/json/tags.json +5 -1
  6. package/dist/json/web-types.json +83 -47
  7. package/dist/vuetify-labs.css +2296 -2277
  8. package/dist/vuetify-labs.d.ts +712 -662
  9. package/dist/vuetify-labs.esm.js +269 -227
  10. package/dist/vuetify-labs.esm.js.map +1 -1
  11. package/dist/vuetify-labs.js +268 -226
  12. package/dist/vuetify-labs.min.css +2 -2
  13. package/dist/vuetify.css +32 -4
  14. package/dist/vuetify.d.ts +593 -417
  15. package/dist/vuetify.esm.js +247 -34
  16. package/dist/vuetify.esm.js.map +1 -1
  17. package/dist/vuetify.js +246 -33
  18. package/dist/vuetify.js.map +1 -1
  19. package/dist/vuetify.min.css +2 -2
  20. package/dist/vuetify.min.js +319 -293
  21. package/dist/vuetify.min.js.map +1 -1
  22. package/lib/components/VAutocomplete/VAutocomplete.mjs +5 -2
  23. package/lib/components/VAutocomplete/VAutocomplete.mjs.map +1 -1
  24. package/lib/components/VAutocomplete/index.d.ts +38 -32
  25. package/lib/components/VCheckbox/index.d.ts +14 -14
  26. package/lib/components/VChip/VChip.mjs +2 -2
  27. package/lib/components/VChip/VChip.mjs.map +1 -1
  28. package/lib/components/VChip/index.d.ts +14 -14
  29. package/lib/components/VCombobox/VCombobox.mjs +6 -3
  30. package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
  31. package/lib/components/VCombobox/index.d.ts +38 -32
  32. package/lib/components/VField/VField.mjs +3 -3
  33. package/lib/components/VField/VField.mjs.map +1 -1
  34. package/lib/components/VField/index.d.ts +20 -20
  35. package/lib/components/VFileInput/VFileInput.mjs +0 -1
  36. package/lib/components/VFileInput/VFileInput.mjs.map +1 -1
  37. package/lib/components/VFileInput/index.d.ts +50 -56
  38. package/lib/components/VImg/VImg.mjs +3 -3
  39. package/lib/components/VImg/VImg.mjs.map +1 -1
  40. package/lib/components/VImg/index.d.ts +19 -19
  41. package/lib/components/VInput/VInput.mjs +2 -2
  42. package/lib/components/VInput/VInput.mjs.map +1 -1
  43. package/lib/components/VInput/index.d.ts +14 -14
  44. package/lib/components/VList/VList.mjs +2 -1
  45. package/lib/components/VList/VList.mjs.map +1 -1
  46. package/lib/components/VList/VListItem.css +12 -0
  47. package/lib/components/VList/VListItem.mjs +2 -2
  48. package/lib/components/VList/VListItem.mjs.map +1 -1
  49. package/lib/components/VList/VListItem.sass +5 -0
  50. package/lib/components/VList/index.d.ts +14 -14
  51. package/lib/components/VOverlay/useActivator.mjs +1 -0
  52. package/lib/components/VOverlay/useActivator.mjs.map +1 -1
  53. package/lib/components/VProgressCircular/VProgressCircular.css +3 -1
  54. package/lib/components/VProgressCircular/VProgressCircular.sass +3 -1
  55. package/lib/components/VProgressCircular/_variables.scss +1 -0
  56. package/lib/components/VProgressLinear/VProgressLinear.css +5 -2
  57. package/lib/components/VProgressLinear/VProgressLinear.sass +3 -0
  58. package/lib/components/VProgressLinear/_variables.scss +1 -1
  59. package/lib/components/VRadioGroup/index.d.ts +14 -14
  60. package/lib/components/VRangeSlider/index.d.ts +14 -14
  61. package/lib/components/VSelect/VSelect.mjs +31 -2
  62. package/lib/components/VSelect/VSelect.mjs.map +1 -1
  63. package/lib/components/VSelect/index.d.ts +38 -32
  64. package/lib/components/VSlider/index.d.ts +14 -14
  65. package/lib/components/VSwitch/index.d.ts +14 -14
  66. package/lib/components/VTextField/VTextField.mjs +2 -2
  67. package/lib/components/VTextField/VTextField.mjs.map +1 -1
  68. package/lib/components/VTextField/index.d.ts +83 -77
  69. package/lib/components/VTextarea/VTextarea.mjs +8 -5
  70. package/lib/components/VTextarea/VTextarea.mjs.map +1 -1
  71. package/lib/components/VTextarea/index.d.ts +56 -50
  72. package/lib/components/VToolbar/VToolbar.css +2 -0
  73. package/lib/components/VToolbar/VToolbar.sass +2 -0
  74. package/lib/components/VVirtualScroll/VVirtualScroll.mjs.map +1 -0
  75. package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs.map +1 -0
  76. package/lib/components/VVirtualScroll/index.mjs.map +1 -0
  77. package/lib/components/index.d.ts +576 -403
  78. package/lib/components/index.mjs +2 -1
  79. package/lib/components/index.mjs.map +1 -1
  80. package/lib/composables/proxiedModel.mjs +2 -1
  81. package/lib/composables/proxiedModel.mjs.map +1 -1
  82. package/lib/composables/theme.mjs +1 -1
  83. package/lib/composables/theme.mjs.map +1 -1
  84. package/lib/entry-bundler.mjs +1 -1
  85. package/lib/framework.mjs +1 -1
  86. package/lib/index.d.ts +16 -15
  87. package/lib/labs/VDataTable/VDataTable.mjs +4 -4
  88. package/lib/labs/VDataTable/VDataTable.mjs.map +1 -1
  89. package/lib/labs/VDataTable/VDataTableRows.mjs +5 -7
  90. package/lib/labs/VDataTable/VDataTableRows.mjs.map +1 -1
  91. package/lib/labs/VDataTable/VDataTableServer.mjs +4 -3
  92. package/lib/labs/VDataTable/VDataTableServer.mjs.map +1 -1
  93. package/lib/labs/VDataTable/VDataTableVirtual.mjs +5 -3
  94. package/lib/labs/VDataTable/VDataTableVirtual.mjs.map +1 -1
  95. package/lib/labs/VDataTable/index.d.ts +137 -111
  96. package/lib/labs/components.d.ts +138 -261
  97. package/lib/labs/components.mjs +0 -1
  98. package/lib/labs/components.mjs.map +1 -1
  99. package/lib/util/helpers.mjs +1 -1
  100. package/lib/util/helpers.mjs.map +1 -1
  101. package/package.json +2 -2
  102. package/lib/labs/VVirtualScroll/VVirtualScroll.mjs.map +0 -1
  103. package/lib/labs/VVirtualScroll/VVirtualScrollItem.mjs.map +0 -1
  104. package/lib/labs/VVirtualScroll/index.mjs.map +0 -1
  105. /package/lib/{labs → components}/VVirtualScroll/VVirtualScroll.css +0 -0
  106. /package/lib/{labs → components}/VVirtualScroll/VVirtualScroll.mjs +0 -0
  107. /package/lib/{labs → components}/VVirtualScroll/VVirtualScroll.sass +0 -0
  108. /package/lib/{labs → components}/VVirtualScroll/VVirtualScrollItem.mjs +0 -0
  109. /package/lib/{labs → components}/VVirtualScroll/index.d.ts +0 -0
  110. /package/lib/{labs → components}/VVirtualScroll/index.mjs +0 -0
package/dist/vuetify.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vuetify v3.2.0-dev-20230405.0
2
+ * Vuetify v3.2.0-dev-20230415.0
3
3
  * Forged by John Leider
4
4
  * Released under the MIT License.
5
5
  */
@@ -343,7 +343,7 @@
343
343
  }
344
344
  const onRE = /^on[^a-z]/;
345
345
  const isOn = key => onRE.test(key);
346
- const EventProp = [Function, Array];
346
+ const EventProp = () => [Function, Array];
347
347
  function hasEvent(props, name) {
348
348
  name = 'on' + vue.capitalize(name);
349
349
  return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`]);
@@ -1703,7 +1703,7 @@
1703
1703
  if (/^on-[a-z]/.test(key)) {
1704
1704
  createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
1705
1705
  } else {
1706
- createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`]);
1706
+ createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`]);
1707
1707
  createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
1708
1708
  createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`]);
1709
1709
  }
@@ -1841,7 +1841,8 @@
1841
1841
  });
1842
1842
  const model = vue.computed({
1843
1843
  get() {
1844
- return transformIn(isControlled.value ? props[prop] : internal.value);
1844
+ const externalValue = props[prop];
1845
+ return transformIn(isControlled.value ? externalValue : internal.value);
1845
1846
  },
1846
1847
  set(internalValue) {
1847
1848
  const newValue = transformOut(internalValue);
@@ -2715,9 +2716,9 @@
2715
2716
  ...makeTransitionProps()
2716
2717
  },
2717
2718
  emits: {
2718
- loadstart: event => true,
2719
- load: event => true,
2720
- error: event => true
2719
+ loadstart: value => true,
2720
+ load: value => true,
2721
+ error: value => true
2721
2722
  },
2722
2723
  setup(props, _ref) {
2723
2724
  let {
@@ -5342,9 +5343,9 @@
5342
5343
  default: 'filled',
5343
5344
  validator: v => allowedVariants$1.includes(v)
5344
5345
  },
5345
- 'onClick:clear': EventProp,
5346
- 'onClick:appendInner': EventProp,
5347
- 'onClick:prependInner': EventProp,
5346
+ 'onClick:clear': EventProp(),
5347
+ 'onClick:appendInner': EventProp(),
5348
+ 'onClick:prependInner': EventProp(),
5348
5349
  ...makeThemeProps(),
5349
5350
  ...makeLoaderProps()
5350
5351
  }, 'v-field');
@@ -5890,8 +5891,8 @@
5890
5891
  default: 'horizontal',
5891
5892
  validator: v => ['horizontal', 'vertical'].includes(v)
5892
5893
  },
5893
- 'onClick:prepend': EventProp,
5894
- 'onClick:append': EventProp,
5894
+ 'onClick:prepend': EventProp(),
5895
+ 'onClick:append': EventProp(),
5895
5896
  ...makeDensityProps(),
5896
5897
  ...makeValidationProps()
5897
5898
  }, 'v-input');
@@ -6122,6 +6123,7 @@
6122
6123
  type: String,
6123
6124
  default: 'text'
6124
6125
  },
6126
+ modelModifiers: Object,
6125
6127
  ...makeVInputProps(),
6126
6128
  ...makeVFieldProps()
6127
6129
  }, 'v-text-field');
@@ -6196,7 +6198,7 @@
6196
6198
  function onInput(e) {
6197
6199
  const el = e.target;
6198
6200
  model.value = el.value;
6199
- if (['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
6201
+ if (props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
6200
6202
  const caretPosition = [el.selectionStart, el.selectionEnd];
6201
6203
  vue.nextTick(() => {
6202
6204
  el.selectionStart = caretPosition[0];
@@ -6833,8 +6835,8 @@
6833
6835
  type: Boolean,
6834
6836
  default: true
6835
6837
  },
6836
- onClick: EventProp,
6837
- onClickOnce: EventProp,
6838
+ onClick: EventProp(),
6839
+ onClickOnce: EventProp(),
6838
6840
  ...makeBorderProps(),
6839
6841
  ...makeDensityProps(),
6840
6842
  ...makeElevationProps(),
@@ -7678,8 +7680,8 @@
7678
7680
  subtitle: [String, Number, Boolean],
7679
7681
  title: [String, Number, Boolean],
7680
7682
  value: null,
7681
- onClick: EventProp,
7682
- onClickOnce: EventProp,
7683
+ onClick: EventProp(),
7684
+ onClickOnce: EventProp(),
7683
7685
  ...makeBorderProps(),
7684
7686
  ...makeDensityProps(),
7685
7687
  ...makeDimensionProps(),
@@ -8221,7 +8223,8 @@
8221
8223
  }
8222
8224
  function focus(location) {
8223
8225
  if (!contentRef.value) return;
8224
- const focusable = [...contentRef.value.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')].filter(el => !el.hasAttribute('disabled'));
8226
+ const targets = ['button', '[href]', 'input', 'select', 'textarea', '[tabindex]'].map(s => `${s}:not([tabindex="-1"])`).join(', ');
8227
+ const focusable = [...contentRef.value.querySelectorAll(targets)].filter(el => !el.hasAttribute('disabled'));
8225
8228
  const idx = focusable.indexOf(document.activeElement);
8226
8229
  if (!location) {
8227
8230
  if (!contentRef.value.contains(document.activeElement)) {
@@ -8402,6 +8405,7 @@
8402
8405
  isActive.value = !isActive.value;
8403
8406
  },
8404
8407
  mouseenter: e => {
8408
+ if (e.sourceCapabilities?.firesTouchEvents) return;
8405
8409
  isHovered = true;
8406
8410
  activatorEl.value = e.currentTarget || e.target;
8407
8411
  runOpenDelay();
@@ -9928,6 +9932,9 @@
9928
9932
  });
9929
9933
  });
9930
9934
  const selected = vue.computed(() => selections.value.map(selection => selection.props.value));
9935
+ const isFocused = vue.ref(false);
9936
+ let keyboardLookupPrefix = '';
9937
+ let keyboardLookupLastTime;
9931
9938
  const displayItems = vue.computed(() => {
9932
9939
  if (props.hideSelected) {
9933
9940
  return items.value.filter(item => !selections.value.some(s => s === item));
@@ -9964,6 +9971,26 @@
9964
9971
  } else if (e.key === 'End') {
9965
9972
  listRef.value?.focus('last');
9966
9973
  }
9974
+
9975
+ // html select hotkeys
9976
+ const KEYBOARD_LOOKUP_THRESHOLD = 1000; // milliseconds
9977
+
9978
+ function checkPrintable(e) {
9979
+ const isPrintableChar = e.key.length === 1;
9980
+ const noModifier = !e.ctrlKey && !e.metaKey && !e.altKey;
9981
+ return isPrintableChar && noModifier;
9982
+ }
9983
+ if (props.multiple || !checkPrintable(e)) return;
9984
+ const now = performance.now();
9985
+ if (now - keyboardLookupLastTime > KEYBOARD_LOOKUP_THRESHOLD) {
9986
+ keyboardLookupPrefix = '';
9987
+ }
9988
+ keyboardLookupPrefix += e.key.toLowerCase();
9989
+ keyboardLookupLastTime = now;
9990
+ const item = items.value.find(item => item.title.toLowerCase().startsWith(keyboardLookupPrefix));
9991
+ if (item !== undefined) {
9992
+ model.value = [item];
9993
+ }
9967
9994
  }
9968
9995
  function select(item) {
9969
9996
  if (props.multiple) {
@@ -9993,7 +10020,9 @@
9993
10020
  useRender(() => {
9994
10021
  const hasChips = !!(props.chips || slots.chip);
9995
10022
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots.prepend || slots.append || slots['no-data']);
10023
+ const isDirty = model.value.length > 0;
9996
10024
  const [textFieldProps] = VTextField.filterProps(props);
10025
+ const placeholder = isDirty || !isFocused.value && props.label && !props.persistentPlaceholder ? undefined : props.placeholder;
9997
10026
  return vue.createVNode(VTextField, vue.mergeProps({
9998
10027
  "ref": vTextFieldRef
9999
10028
  }, textFieldProps, {
@@ -10001,8 +10030,10 @@
10001
10030
  "onUpdate:modelValue": v => {
10002
10031
  if (v == null) model.value = [];
10003
10032
  },
10033
+ "focused": isFocused.value,
10034
+ "onUpdate:focused": $event => isFocused.value = $event,
10004
10035
  "validationValue": model.externalValue,
10005
- "dirty": model.value.length > 0,
10036
+ "dirty": isDirty,
10006
10037
  "class": ['v-select', {
10007
10038
  'v-select--active-menu': menu.value,
10008
10039
  'v-select--chips': !!props.chips,
@@ -10011,6 +10042,7 @@
10011
10042
  }],
10012
10043
  "appendInnerIcon": props.menuIcon,
10013
10044
  "readonly": true,
10045
+ "placeholder": placeholder,
10014
10046
  "onClick:clear": onClear,
10015
10047
  "onMousedown:control": onMousedownControl,
10016
10048
  "onBlur": onBlur,
@@ -10059,7 +10091,8 @@
10059
10091
  } = _ref2;
10060
10092
  return props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
10061
10093
  "modelValue": isSelected,
10062
- "ripple": false
10094
+ "ripple": false,
10095
+ "tabindex": "-1"
10063
10096
  }, null) : undefined;
10064
10097
  }
10065
10098
  });
@@ -10386,6 +10419,7 @@
10386
10419
  useRender(() => {
10387
10420
  const hasChips = !!(props.chips || slots.chip);
10388
10421
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots.prepend || slots.append || slots['no-data']);
10422
+ const isDirty = model.value.length > 0;
10389
10423
  const [textFieldProps] = VTextField.filterProps(props);
10390
10424
  return vue.createVNode(VTextField, vue.mergeProps({
10391
10425
  "ref": vTextFieldRef
@@ -10395,7 +10429,7 @@
10395
10429
  if (v == null) model.value = [];
10396
10430
  },
10397
10431
  "validationValue": model.externalValue,
10398
- "dirty": model.value.length > 0,
10432
+ "dirty": isDirty,
10399
10433
  "onInput": onInput,
10400
10434
  "class": ['v-autocomplete', {
10401
10435
  'v-autocomplete--active-menu': menu.value,
@@ -10405,6 +10439,7 @@
10405
10439
  }],
10406
10440
  "appendInnerIcon": props.menuIcon,
10407
10441
  "readonly": props.readonly,
10442
+ "placeholder": isDirty ? undefined : props.placeholder,
10408
10443
  "onClick:clear": onClear,
10409
10444
  "onMousedown:control": onMousedownControl,
10410
10445
  "onFocus": () => isFocused.value = true,
@@ -10451,7 +10486,8 @@
10451
10486
  } = _ref2;
10452
10487
  return props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
10453
10488
  "modelValue": isSelected,
10454
- "ripple": false
10489
+ "ripple": false,
10490
+ "tabindex": "-1"
10455
10491
  }, null) : undefined;
10456
10492
  },
10457
10493
  title: () => {
@@ -13567,7 +13603,7 @@
13567
13603
  textColorClasses,
13568
13604
  textColorStyles
13569
13605
  } = useTextColor(color);
13570
- const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v || [])), v => {
13606
+ const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
13571
13607
  const transformed = transformOut(v);
13572
13608
  return props.multiple ? transformed : transformed[0] ?? null;
13573
13609
  });
@@ -13745,6 +13781,7 @@
13745
13781
  useRender(() => {
13746
13782
  const hasChips = !!(props.chips || slots.chip);
13747
13783
  const hasList = !!(!props.hideNoData || displayItems.value.length || slots.prepend || slots.append || slots['no-data']);
13784
+ const isDirty = model.value.length > 0;
13748
13785
  const [textFieldProps] = VTextField.filterProps(props);
13749
13786
  return vue.createVNode(VTextField, vue.mergeProps({
13750
13787
  "ref": vTextFieldRef
@@ -13754,7 +13791,7 @@
13754
13791
  if (v == null) model.value = [];
13755
13792
  }],
13756
13793
  "validationValue": model.externalValue,
13757
- "dirty": model.value.length > 0,
13794
+ "dirty": isDirty,
13758
13795
  "class": ['v-combobox', {
13759
13796
  'v-combobox--active-menu': menu.value,
13760
13797
  'v-combobox--chips': !!props.chips,
@@ -13763,6 +13800,7 @@
13763
13800
  }],
13764
13801
  "appendInnerIcon": props.items.length ? props.menuIcon : undefined,
13765
13802
  "readonly": props.readonly,
13803
+ "placeholder": isDirty ? undefined : props.placeholder,
13766
13804
  "onClick:clear": onClear,
13767
13805
  "onMousedown:control": onMousedownControl,
13768
13806
  "onFocus": () => isFocused.value = true,
@@ -13809,7 +13847,8 @@
13809
13847
  } = _ref2;
13810
13848
  return props.multiple && !props.hideSelected ? vue.createVNode(VCheckboxBtn, {
13811
13849
  "modelValue": isSelected,
13812
- "ripple": false
13850
+ "ripple": false,
13851
+ "tabindex": "-1"
13813
13852
  }, null) : undefined;
13814
13853
  },
13815
13854
  title: () => {
@@ -14219,7 +14258,6 @@
14219
14258
  multiple: Boolean,
14220
14259
  hint: String,
14221
14260
  persistentHint: Boolean,
14222
- placeholder: String,
14223
14261
  showSize: {
14224
14262
  type: [Boolean, Number],
14225
14263
  default: false,
@@ -17435,6 +17473,7 @@
17435
17473
  validator: v => !isNaN(parseFloat(v))
17436
17474
  },
17437
17475
  suffix: String,
17476
+ modelModifiers: Object,
17438
17477
  ...makeVInputProps(),
17439
17478
  ...makeVFieldProps()
17440
17479
  },
@@ -17499,12 +17538,14 @@
17499
17538
  }
17500
17539
  function onInput(e) {
17501
17540
  const el = e.target;
17502
- const caretPosition = [el.selectionStart, el.selectionEnd];
17503
17541
  model.value = el.value;
17504
- vue.nextTick(() => {
17505
- el.selectionStart = caretPosition[0];
17506
- el.selectionEnd = caretPosition[1];
17507
- });
17542
+ if (props.modelModifiers?.trim) {
17543
+ const caretPosition = [el.selectionStart, el.selectionEnd];
17544
+ vue.nextTick(() => {
17545
+ el.selectionStart = caretPosition[0];
17546
+ el.selectionEnd = caretPosition[1];
17547
+ });
17548
+ }
17508
17549
  }
17509
17550
  const sizerRef = vue.ref();
17510
17551
  function calculateInputHeight() {
@@ -17993,6 +18034,177 @@
17993
18034
  }
17994
18035
  });
17995
18036
 
18037
+ const VVirtualScrollItem = genericComponent()({
18038
+ name: 'VVirtualScrollItem',
18039
+ props: {
18040
+ dynamicHeight: Boolean
18041
+ },
18042
+ emits: {
18043
+ 'update:height': height => true
18044
+ },
18045
+ setup(props, _ref) {
18046
+ let {
18047
+ emit,
18048
+ slots
18049
+ } = _ref;
18050
+ const {
18051
+ resizeRef,
18052
+ contentRect
18053
+ } = useResizeObserver();
18054
+ useToggleScope(() => props.dynamicHeight, () => {
18055
+ vue.watch(() => contentRect.value?.height, height => {
18056
+ if (height != null) emit('update:height', height);
18057
+ });
18058
+ });
18059
+ function updateHeight() {
18060
+ if (props.dynamicHeight && contentRect.value) {
18061
+ emit('update:height', contentRect.value.height);
18062
+ }
18063
+ }
18064
+ vue.onUpdated(updateHeight);
18065
+ useRender(() => vue.createVNode("div", {
18066
+ "ref": props.dynamicHeight ? resizeRef : undefined,
18067
+ "class": "v-virtual-scroll__item"
18068
+ }, [slots.default?.()]));
18069
+ }
18070
+ });
18071
+
18072
+ // Types
18073
+
18074
+ const UP = -1;
18075
+ const DOWN = 1;
18076
+ const VVirtualScroll = genericComponent()({
18077
+ name: 'VVirtualScroll',
18078
+ props: {
18079
+ items: {
18080
+ type: Array,
18081
+ default: () => []
18082
+ },
18083
+ itemHeight: [Number, String],
18084
+ visibleItems: [Number, String],
18085
+ ...makeDimensionProps()
18086
+ },
18087
+ setup(props, _ref) {
18088
+ let {
18089
+ slots
18090
+ } = _ref;
18091
+ const first = vue.ref(0);
18092
+ const baseItemHeight = vue.ref(props.itemHeight);
18093
+ const itemHeight = vue.computed({
18094
+ get: () => parseInt(baseItemHeight.value ?? 0, 10),
18095
+ set(val) {
18096
+ baseItemHeight.value = val;
18097
+ }
18098
+ });
18099
+ const rootEl = vue.ref();
18100
+ const {
18101
+ resizeRef,
18102
+ contentRect
18103
+ } = useResizeObserver();
18104
+ vue.watchEffect(() => {
18105
+ resizeRef.value = rootEl.value;
18106
+ });
18107
+ const display = useDisplay();
18108
+ const sizeMap = new Map();
18109
+ let sizes = createRange(props.items.length).map(() => itemHeight.value);
18110
+ const visibleItems = vue.computed(() => {
18111
+ return props.visibleItems ? parseInt(props.visibleItems, 10) : Math.max(12, Math.ceil((contentRect.value?.height ?? display.height.value) / itemHeight.value * 1.7 + 1));
18112
+ });
18113
+ function handleItemResize(index, height) {
18114
+ itemHeight.value = Math.max(itemHeight.value, height);
18115
+ sizes[index] = height;
18116
+ sizeMap.set(props.items[index], height);
18117
+ }
18118
+ function calculateOffset(index) {
18119
+ return sizes.slice(0, index).reduce((curr, value) => curr + (value || itemHeight.value), 0);
18120
+ }
18121
+ function calculateMidPointIndex(scrollTop) {
18122
+ let start = 0;
18123
+ let end = props.items.length;
18124
+ while (start <= end) {
18125
+ const middle = start + Math.floor((end - start) / 2);
18126
+ const middleOffset = calculateOffset(middle);
18127
+ if (middleOffset === scrollTop) {
18128
+ return middle;
18129
+ } else if (middleOffset < scrollTop) {
18130
+ start = middle + 1;
18131
+ } else if (middleOffset > scrollTop) {
18132
+ end = middle - 1;
18133
+ }
18134
+ }
18135
+ return start;
18136
+ }
18137
+ let lastScrollTop = 0;
18138
+ function handleScroll() {
18139
+ if (!rootEl.value || !contentRect.value) return;
18140
+ const height = contentRect.value.height;
18141
+ const scrollTop = rootEl.value.scrollTop;
18142
+ const direction = scrollTop < lastScrollTop ? UP : DOWN;
18143
+ const midPointIndex = calculateMidPointIndex(scrollTop + height / 2);
18144
+ const buffer = Math.round(visibleItems.value / 3);
18145
+ if (direction === UP && midPointIndex <= first.value + buffer * 2 - 1) {
18146
+ first.value = clamp(midPointIndex - buffer, 0, props.items.length);
18147
+ } else if (direction === DOWN && midPointIndex >= first.value + buffer * 2 - 1) {
18148
+ first.value = clamp(midPointIndex - buffer, 0, props.items.length - visibleItems.value);
18149
+ }
18150
+ lastScrollTop = rootEl.value.scrollTop;
18151
+ }
18152
+ function scrollToIndex(index) {
18153
+ if (!rootEl.value) return;
18154
+ const offset = calculateOffset(index);
18155
+ rootEl.value.scrollTop = offset;
18156
+ }
18157
+ const last = vue.computed(() => Math.min(props.items.length, first.value + visibleItems.value));
18158
+ const computedItems = vue.computed(() => props.items.slice(first.value, last.value));
18159
+ const paddingTop = vue.computed(() => calculateOffset(first.value));
18160
+ const paddingBottom = vue.computed(() => calculateOffset(props.items.length) - calculateOffset(last.value));
18161
+ const {
18162
+ dimensionStyles
18163
+ } = useDimension(props);
18164
+ vue.onMounted(() => {
18165
+ if (!itemHeight.value) {
18166
+ // If itemHeight prop is not set, then calculate an estimated height from the average of inital items
18167
+ itemHeight.value = sizes.slice(first.value, last.value).reduce((curr, height) => curr + height, 0) / visibleItems.value;
18168
+ }
18169
+ });
18170
+ vue.watch(() => props.items.length, () => {
18171
+ sizes = createRange(props.items.length).map(() => itemHeight.value);
18172
+ sizeMap.forEach((height, item) => {
18173
+ const index = props.items.indexOf(item);
18174
+ if (index === -1) {
18175
+ sizeMap.delete(item);
18176
+ } else {
18177
+ sizes[index] = height;
18178
+ }
18179
+ });
18180
+ });
18181
+ useRender(() => vue.createVNode("div", {
18182
+ "ref": rootEl,
18183
+ "class": "v-virtual-scroll",
18184
+ "onScroll": handleScroll,
18185
+ "style": dimensionStyles.value
18186
+ }, [vue.createVNode("div", {
18187
+ "class": "v-virtual-scroll__container",
18188
+ "style": {
18189
+ paddingTop: convertToUnit(paddingTop.value),
18190
+ paddingBottom: convertToUnit(paddingBottom.value)
18191
+ }
18192
+ }, [computedItems.value.map((item, index) => vue.createVNode(VVirtualScrollItem, {
18193
+ "key": index,
18194
+ "dynamicHeight": !props.itemHeight,
18195
+ "onUpdate:height": height => handleItemResize(index + first.value, height)
18196
+ }, {
18197
+ default: () => [slots.default?.({
18198
+ item,
18199
+ index: index + first.value
18200
+ })]
18201
+ }))])]));
18202
+ return {
18203
+ scrollToIndex
18204
+ };
18205
+ }
18206
+ });
18207
+
17996
18208
  var components = /*#__PURE__*/Object.freeze({
17997
18209
  __proto__: null,
17998
18210
  VAlert: VAlert,
@@ -18125,6 +18337,7 @@
18125
18337
  VToolbarTitle: VToolbarTitle,
18126
18338
  VTooltip: VTooltip,
18127
18339
  VValidation: VValidation,
18340
+ VVirtualScroll: VVirtualScroll,
18128
18341
  VWindow: VWindow,
18129
18342
  VWindowItem: VWindowItem
18130
18343
  });
@@ -18337,7 +18550,7 @@
18337
18550
  locale
18338
18551
  };
18339
18552
  }
18340
- const version$1 = "3.2.0-dev-20230405.0";
18553
+ const version$1 = "3.2.0-dev-20230415.0";
18341
18554
  createVuetify$1.version = version$1;
18342
18555
 
18343
18556
  // Vue's inject() can only be used in setup
@@ -18357,7 +18570,7 @@
18357
18570
  ...options
18358
18571
  });
18359
18572
  };
18360
- const version = "3.2.0-dev-20230405.0";
18573
+ const version = "3.2.0-dev-20230415.0";
18361
18574
  createVuetify.version = version;
18362
18575
 
18363
18576
  exports.components = components;