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.
- package/dist/json/attributes.json +14 -10
- package/dist/json/importMap.json +76 -76
- package/dist/json/tags.json +1 -0
- package/dist/json/web-types.json +26 -24
- package/dist/vuetify-labs.css +127 -111
- package/dist/vuetify-labs.d.ts +178 -76
- package/dist/vuetify-labs.esm.js +486 -337
- package/dist/vuetify-labs.esm.js.map +1 -1
- package/dist/vuetify-labs.js +485 -336
- package/dist/vuetify-labs.min.css +2 -2
- package/dist/vuetify.css +36 -20
- package/dist/vuetify.d.ts +157 -93
- package/dist/vuetify.esm.js +469 -326
- package/dist/vuetify.esm.js.map +1 -1
- package/dist/vuetify.js +468 -325
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +2 -2
- package/dist/vuetify.min.js +688 -669
- package/dist/vuetify.min.js.map +1 -1
- package/lib/components/VAutocomplete/VAutocomplete.mjs +48 -35
- package/lib/components/VAutocomplete/VAutocomplete.mjs.map +1 -1
- package/lib/components/VBtn/VBtn.mjs +1 -1
- package/lib/components/VBtn/VBtn.mjs.map +1 -1
- package/lib/components/VCheckbox/index.d.mts +28 -16
- package/lib/components/VCombobox/VCombobox.mjs +48 -35
- package/lib/components/VCombobox/VCombobox.mjs.map +1 -1
- package/lib/components/VField/VField.css +17 -6
- package/lib/components/VField/VField.sass +17 -6
- package/lib/components/VField/_variables.scss +2 -2
- package/lib/components/VIcon/VIcon.css +1 -0
- package/lib/components/VIcon/VIcon.sass +1 -0
- package/lib/components/VImg/VImg.css +4 -2
- package/lib/components/VImg/VImg.mjs +4 -2
- package/lib/components/VImg/VImg.mjs.map +1 -1
- package/lib/components/VImg/VImg.sass +3 -4
- package/lib/components/VOverlay/VOverlay.css +2 -0
- package/lib/components/VOverlay/VOverlay.sass +3 -1
- package/lib/components/VOverlay/scrollStrategies.mjs +3 -1
- package/lib/components/VOverlay/scrollStrategies.mjs.map +1 -1
- package/lib/components/VRadio/index.d.mts +14 -8
- package/lib/components/VRadioGroup/index.d.mts +14 -8
- package/lib/components/VResponsive/VResponsive.css +6 -11
- package/lib/components/VResponsive/VResponsive.sass +5 -10
- package/lib/components/VSelect/VSelect.mjs +43 -31
- package/lib/components/VSelect/VSelect.mjs.map +1 -1
- package/lib/components/VSelect/useScrolling.mjs +69 -0
- package/lib/components/VSelect/useScrolling.mjs.map +1 -0
- package/lib/components/VSelectionControl/VSelectionControl.mjs +2 -2
- package/lib/components/VSelectionControl/VSelectionControl.mjs.map +1 -1
- package/lib/components/VSelectionControl/index.d.mts +14 -8
- package/lib/components/VSelectionControlGroup/VSelectionControlGroup.mjs +4 -1
- package/lib/components/VSelectionControlGroup/VSelectionControlGroup.mjs.map +1 -1
- package/lib/components/VSelectionControlGroup/index.d.mts +14 -8
- package/lib/components/VSwitch/index.d.mts +14 -8
- package/lib/components/VTextField/VTextField.css +5 -0
- package/lib/components/VTextField/VTextField.mjs +6 -2
- package/lib/components/VTextField/VTextField.mjs.map +1 -1
- package/lib/components/VTextField/VTextField.sass +5 -0
- package/lib/components/VTextField/_variables.scss +1 -0
- package/lib/components/VVirtualScroll/VVirtualScroll.mjs +50 -24
- package/lib/components/VVirtualScroll/VVirtualScroll.mjs.map +1 -1
- package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs +13 -23
- package/lib/components/VVirtualScroll/VVirtualScrollItem.mjs.map +1 -1
- package/lib/components/VVirtualScroll/index.d.mts +37 -15
- package/lib/components/index.d.mts +134 -70
- package/lib/composables/filter.mjs +9 -7
- package/lib/composables/filter.mjs.map +1 -1
- package/lib/composables/resizeObserver.mjs +6 -1
- package/lib/composables/resizeObserver.mjs.map +1 -1
- package/lib/composables/virtual.mjs +17 -17
- package/lib/composables/virtual.mjs.map +1 -1
- package/lib/entry-bundler.mjs +1 -1
- package/lib/framework.mjs +1 -1
- package/lib/index.d.mts +23 -23
- package/lib/labs/VDataTable/VDataTableVirtual.mjs +12 -10
- package/lib/labs/VDataTable/VDataTableVirtual.mjs.map +1 -1
- package/lib/labs/VDataTable/composables/headers.mjs +6 -2
- package/lib/labs/VDataTable/composables/headers.mjs.map +1 -1
- package/lib/labs/VDataTable/index.d.mts +44 -6
- package/lib/labs/components.d.mts +44 -6
- package/lib/util/getScrollParent.mjs +7 -1
- package/lib/util/getScrollParent.mjs.map +1 -1
- package/package.json +2 -2
package/dist/vuetify.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Vuetify v3.3.
|
|
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
|
-
|
|
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":
|
|
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:
|
|
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.
|
|
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
|
-
}, [
|
|
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
|
-
}, [
|
|
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)),
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
|
|
10615
|
-
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10629
|
-
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
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
|
-
|
|
10778
|
-
|
|
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
|
-
|
|
10794
|
-
|
|
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,
|
|
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)),
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
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,
|
|
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)),
|
|
14643
|
-
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
|
|
14647
|
-
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
|
|
14651
|
-
|
|
14652
|
-
|
|
14653
|
-
|
|
14654
|
-
|
|
14655
|
-
|
|
14656
|
-
|
|
14657
|
-
|
|
14658
|
-
|
|
14659
|
-
|
|
14660
|
-
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
14667
|
-
|
|
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.
|
|
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.
|
|
20188
|
+
const version = "3.3.7";
|
|
20046
20189
|
createVuetify.version = version;
|
|
20047
20190
|
|
|
20048
20191
|
exports.components = components;
|