@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
1 lines • 49 kB
Source Map (JSON)
{"version":3,"file":"scroller.cjs","sources":["../../../components/scroller/modules/core_scroller.vue","../../../components/scroller/modules/scroller_item.vue","../../../components/scroller/modules/dynamic_scroller.vue","../../../components/scroller/scroller.vue"],"sourcesContent":["<!-- eslint-disable max-len -->\n<template>\n <div\n ref=\"scroller\"\n class=\"vue-recycle-scroller\"\n :class=\"{\n ready,\n [`direction-${direction}`]: true,\n }\"\n @scroll.passive=\"handleScroll\"\n >\n <component\n :is=\"listTag\"\n ref=\"wrapper\"\n :style=\"{ [direction === 'vertical' ? 'minHeight' : 'minWidth']: `${totalSize}px` }\"\n class=\"vue-recycle-scroller__item-wrapper\"\n :class=\"listClass\"\n >\n <component\n :is=\"itemTag\"\n v-for=\"view in pool\"\n :key=\"view.nr.id\"\n :style=\"ready ? {\n transform: `translate${direction === 'vertical' ? 'Y' : 'X'}(${view.position}px) translate${direction === 'vertical' ? 'X' : 'Y'}(${view.offset}px)`,\n width: undefined,\n height: undefined,\n } : null\"\n class=\"vue-recycle-scroller__item-view\"\n :class=\"[\n itemClass,\n {\n hover: !skipHover && hoverKey === view.nr.key,\n },\n ]\"\n v-on=\"skipHover ? {} : {\n mouseenter: () => { hoverKey = view.nr.key },\n mouseleave: () => { hoverKey = null },\n }\"\n >\n <slot\n :item=\"view.item\"\n :index=\"view.nr.index\"\n :active=\"view.nr.used\"\n />\n </component>\n </component>\n </div>\n</template>\n\n<script setup>\n/*\nThis is a code from external library (https://github.com/Akryum/vue-virtual-scroller/blob/master/packages/vue-virtual-scroller/src/components/RecycleScroller.vue)\nWe have modified it for our own specific use.\n*/\nimport { computed, watch, markRaw, shallowReactive, onMounted, nextTick, reactive, ref } from 'vue';\n\nconst props = defineProps({\n /**\n * List of items you want to display in the scroller.\n */\n items: {\n type: Array,\n required: true,\n },\n\n /**\n *\n * Field used to identify items and optimize managing rendered views\n */\n keyField: {\n type: String,\n default: 'id',\n },\n\n /**\n * Direction of the scroller. Can be either `vertical` or `horizontal`.\n */\n direction: {\n type: String,\n default: 'vertical',\n validator: (value) => ['vertical', 'horizontal'].includes(value),\n },\n\n /**\n * Size of the items in the list.\n * If it is set to null (the default value), it will use variable size mode.\n */\n itemSize: {\n type: Number,\n default: null,\n },\n\n /**\n * Minimum size used if the height (or width in horizontal mode) of an item is unknown.\n */\n minItemSize: {\n type: [Number, String],\n default: null,\n },\n\n /**\n * Field used to get the item's size in variable size mode.\n */\n sizeField: {\n type: String,\n default: 'size',\n },\n\n /**\n * Amount of pixel to add to edges of the scrolling visible area to start rendering items further away.\n */\n buffer: {\n type: Number,\n default: 200,\n },\n\n /**\n * If true, the hover state will be skipped.\n * This can be useful if you want to use the hover state for other purposes.\n */\n skipHover: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The element to render as the list's wrapper.\n */\n listTag: {\n type: String,\n default: 'div',\n },\n\n /**\n * The element to render as the list item.\n */\n itemTag: {\n type: String,\n default: 'div',\n },\n\n /**\n * The custom classes added to the item list wrapper.\n */\n listClass: {\n type: [String, Object, Array],\n default: '',\n },\n\n /**\n * The custom classes added to each item.\n */\n itemClass: {\n type: [String, Object, Array],\n default: '',\n },\n});\n\nconst emit = defineEmits(['user-position']);\n\nconst views = reactive(new Map());\n// const reactiveItems = reactive(props.items);\nconst unusedViews = reactive(new Map());\nconst updateTimeout = null;\nconst pool = ref([]);\nconst hoverKey = ref(null);\nconst ready = ref(false);\nconst scroller = ref(null);\nconst userPosition = ref('top');\n\nlet startIndex = 0;\nlet endIndex = 0;\nlet scrollDirty = false;\nlet lastUpdateScrollPosition = 0;\nlet sortTimer = null;\nlet computedMinItemSize = null;\nlet totalSize = 0;\nlet uid = 0;\n\nconst sizes = computed(() => {\n if (props.itemSize === null) {\n const sizes = {\n '-1': { accumulator: 0 },\n };\n const items = props.items;\n const field = props.sizeField;\n const minItemSize = props.minItemSize;\n let computedMinSize = 10000;\n let accumulator = 0;\n let current;\n for (let i = 0, l = items.length; i < l; i++) {\n current = items[i][field] || minItemSize;\n if (current < computedMinSize) {\n computedMinSize = current;\n }\n accumulator += current;\n sizes[i] = { accumulator, size: current };\n }\n\n computedMinItemSize = computedMinSize;\n return sizes;\n }\n return [];\n});\n\nconst simpleArray = computed(() => {\n return props.items.length && typeof props.items[0] !== 'object';\n});\n\nconst itemIndexByKey = computed(() => {\n const result = {};\n for (let i = 0, l = props.items.length; i < l; i++) {\n result[props.items[i][props.keyField]] = i;\n }\n return result;\n});\n\n// watch(reactiveItems, () => {\n// // if add to the top\n// // _updateVisibleItems(true);\n// // if autoscrolling if add to the bottom\n// // _updateVisibleItems(false, true);\n// });\n\nwatch(sizes, () => {\n _updateVisibleItems(false);\n}, { deep: true });\n\nonMounted(() => {\n nextTick(() => {\n // In SSR mode, render the real number of visible items\n _updateVisibleItems(true);\n ready.value = true;\n });\n});\n\nconst _addView = (pool, index, item, key, type) => {\n const nr = markRaw({\n id: uid++,\n index,\n used: true,\n key,\n type,\n });\n const view = shallowReactive({\n item,\n position: 0,\n nr,\n });\n pool.value.push(view);\n return view;\n};\n\nconst _unuseView = (view, fake = false) => {\n const _unusedViews = unusedViews;\n const type = view.nr.type;\n let unusedPool = _unusedViews.get(type);\n if (!unusedPool) {\n unusedPool = [];\n _unusedViews.set(type, unusedPool);\n }\n unusedPool.push(view);\n if (!fake) {\n view.nr.used = false;\n view.position = -9999;\n }\n};\n\nconst _getScroll = () => {\n const isVertical = props.direction === 'vertical';\n let scrollState;\n\n if (isVertical) {\n scrollState = {\n start: scroller.value.scrollTop,\n end: scroller.value.scrollTop + scroller.value.clientHeight,\n };\n } else {\n scrollState = {\n start: scroller.value.scrollLeft,\n end: scroller.value.scrollLeft + scroller.value.clientWidth,\n };\n }\n\n return scrollState;\n};\n\nconst _itemsLimitError = () => {\n setTimeout(() => {\n // eslint-disable-next-line max-len\n console.error('It seems the scroller element isn\\'t scrolling, so it tries to render all the items at once.', 'Scroller:', scroller);\n // eslint-disable-next-line max-len\n console.error('Make sure the scroller has a fixed height (or width) and \\'overflow-y\\' (or \\'overflow-x\\') set to \\'auto\\' so it can scroll correctly and only render the items visible in the scroll viewport.');\n });\n throw new Error('Rendered items limit reached');\n};\n\nconst _sortViews = () => {\n pool.value.sort((viewA, viewB) => viewA.nr.index - viewB.nr.index);\n};\n\nconst _updateVisibleItems = (checkItem, checkPositionDiff = false) => {\n const itemSize = props.itemSize;\n const minItemSize = computedMinItemSize;\n const keyField = simpleArray.value ? null : props.keyField;\n const items = props.items;\n const count = items.length;\n const _sizes = sizes.value;\n const _views = views;\n const _unusedViews = unusedViews;\n const _pool = pool;\n const _itemIndexByKey = itemIndexByKey;\n let _startIndex, _endIndex;\n let _totalSize;\n let visibleStartIndex, visibleEndIndex;\n\n if (!count) {\n _startIndex = _endIndex = visibleStartIndex = visibleEndIndex = _totalSize = 0;\n } else {\n const scroll = _getScroll();\n\n // Skip update if use hasn't scrolled enough\n if (checkPositionDiff) {\n let positionDiff = scroll.start - lastUpdateScrollPosition.value;\n if (positionDiff < 0) positionDiff = -positionDiff;\n if ((itemSize === null && positionDiff < minItemSize.value) || positionDiff < itemSize) {\n return {\n continuous: true,\n };\n }\n }\n lastUpdateScrollPosition = scroll.start;\n\n const _buffer = props.buffer;\n scroll.start -= _buffer;\n scroll.end += _buffer;\n\n // Variable size mode\n if (itemSize === null) {\n let h;\n let a = 0;\n let b = count - 1;\n let i = ~~(count / 2);\n let oldI;\n\n // Searching for _startIndex\n do {\n oldI = i;\n h = _sizes[i]?.accumulator;\n if (h < scroll.start) {\n a = i;\n } else if (i < count - 1 && _sizes[i + 1]?.accumulator > scroll.start) {\n b = i;\n }\n i = ~~((a + b) / 2);\n } while (i !== oldI);\n i < 0 && (i = 0);\n _startIndex = i;\n\n // For container style\n _totalSize = _sizes[count - 1]?.accumulator;\n\n // Searching for _endIndex\n for (\n _endIndex = i;\n _endIndex < count && _sizes[_endIndex]?.accumulator < scroll.end;\n _endIndex++\n );\n\n if (_endIndex === -1) {\n _endIndex = items.length - 1;\n } else {\n _endIndex++;\n // Bounds\n _endIndex > count && (_endIndex = count);\n }\n\n // search visible _startIndex\n for (\n visibleStartIndex = startIndex;\n visibleStartIndex < count && (_sizes[visibleStartIndex]?.accumulator) < scroll.start;\n visibleStartIndex++\n );\n\n // search visible endIndex\n for (\n visibleEndIndex = visibleStartIndex;\n visibleEndIndex < count && (_sizes[visibleEndIndex]?.accumulator) < scroll.end;\n visibleEndIndex++\n );\n } else {\n // Fixed size mode\n _startIndex = ~~(scroll.start / itemSize);\n const remainer = _startIndex % 1;\n _startIndex -= remainer;\n _endIndex = Math.ceil(scroll.end / itemSize);\n visibleStartIndex = Math.max(0, Math.floor((scroll.start) / itemSize));\n visibleEndIndex = Math.floor((scroll.end) / itemSize);\n\n // Bounds\n _startIndex < 0 && (_startIndex = 0);\n _endIndex > count && (_endIndex = count);\n visibleStartIndex < 0 && (visibleStartIndex = 0);\n visibleEndIndex > count && (visibleEndIndex = count);\n\n _totalSize = Math.ceil(count / 1) * itemSize;\n }\n }\n\n // items limit 1000\n if (_endIndex - _startIndex > 1000) {\n _itemsLimitError();\n }\n\n totalSize = _totalSize;\n\n let view;\n\n const continuous = _startIndex <= endIndex && _endIndex >= _startIndex;\n\n // Unuse views that are no longer visible\n if (continuous) {\n for (let i = 0, l = _pool.value.length; i < l; i++) {\n view = _pool.value[i];\n if (view?.nr.used) {\n // Update view item index\n if (checkItem) {\n view.nr.index = _itemIndexByKey[view.item[keyField]];\n }\n\n // Check if index is still in visible range\n if (\n view.nr.index == null ||\n view.nr.index < _startIndex ||\n view.nr.index >= _endIndex\n ) {\n _unuseView(view);\n }\n }\n }\n }\n\n const unusedIndex = continuous ? null : new Map();\n\n let item, type;\n let v;\n for (let i = _startIndex; i < _endIndex; i++) {\n item = items[i];\n const key = keyField ? item?.[keyField] : item;\n\n if (key == null) {\n throw new Error(`Key is ${key} on item (keyField is '${keyField}')`);\n }\n view = _views.get(key);\n\n if (!itemSize && !_sizes[i]?.size) {\n if (view) _unuseView(view);\n continue;\n }\n\n type = item.type;\n\n let unusedPool = _unusedViews.get(type);\n // let newlyUsedView = false;\n\n // No view assigned to item\n if (!view) {\n if (continuous) {\n // Reuse existing view\n if (unusedPool && unusedPool.length) {\n view = unusedPool.pop();\n } else {\n view = _addView(_pool, i, item, key, type);\n }\n } else {\n // Use existing view\n // We don't care if they are already used\n // because we are not in continous scrolling\n v = unusedIndex.get(type) || 0;\n\n if (!unusedPool || v >= unusedPool.length) {\n view = _addView(_pool, i, item, key, type);\n _unuseView(view, true);\n unusedPool = _unusedViews.get(type);\n }\n\n view = unusedPool[v];\n unusedIndex.set(type, v + 1);\n }\n\n // Assign view to item\n _views.delete(view.nr.key);\n view.nr.used = true;\n view.nr.index = i;\n view.nr.key = key;\n view.nr.type = type;\n _views.set(key, view);\n\n // newlyUsedView = true;\n } else {\n // View already assigned to item\n if (!view.nr.used) {\n view.nr.used = true;\n // newlyUsedView = true;\n if (unusedPool) {\n const index = unusedPool.indexOf(view);\n if (index !== -1) unusedPool.splice(index, 1);\n }\n }\n }\n\n // Always set item in case it's a new object with the same key\n view.item = item;\n\n // if (newlyUsedView) {\n // if (items.length === 0) return;\n // if (i === items.length - 1) emit('scroll-end');\n // if (i === 0) emit('scroll-start');\n // }\n\n // Update position\n if (itemSize === null) {\n view.position = _sizes[i - 1]?.accumulator;\n view.offset = 0;\n } else {\n view.position = Math.floor(i) * itemSize;\n view.offset = (i % 1) * itemSize;\n }\n }\n\n startIndex = _startIndex;\n endIndex = _endIndex;\n\n // After the user has finished scrolling\n // Sort views so text selection is correct\n clearTimeout(sortTimer);\n sortTimer = setTimeout(_sortViews, 300);\n\n return {\n continuous,\n };\n};\n\nconst _scrollToPosition = (position) => {\n const direction = props.direction === 'vertical'\n ? { scroll: 'scrollTop', start: 'top' }\n : { scroll: 'scrollLeft', start: 'left' };\n\n const viewport = scroller.value;\n const scrollDirection = direction.scroll;\n\n viewport[scrollDirection] = position;\n};\n\nconst scrollToItem = (index) => {\n let scroll;\n if (props.itemSize === null) {\n scroll = index > 0 ? sizes.value[index - 1]?.accumulator : 0;\n } else {\n scroll = Math.floor(index) * props.itemSize;\n }\n _scrollToPosition(scroll);\n};\n\nconst handleScroll = () => {\n const container = scroller.value;\n\n if (userPosition.value !== 'middle') {\n userPosition.value = 'middle';\n emit('user-position', 'middle');\n }\n\n // Check if the scroll is at the top of the container\n if (container.scrollTop === 0) {\n userPosition.value = 'top';\n emit('user-position', 'top');\n }\n\n // Check if the scroll is at the bottom of the container\n if (container.scrollTop + container.clientHeight === container.scrollHeight) {\n userPosition.value = 'bottom';\n emit('user-position', 'bottom');\n }\n\n if (!scrollDirty) {\n scrollDirty = true;\n if (updateTimeout) return;\n\n const requestUpdate = () => requestAnimationFrame(() => {\n scrollDirty = false;\n _updateVisibleItems(false, true);\n });\n\n requestUpdate();\n }\n};\n\ndefineExpose({\n scrollToItem,\n _updateVisibleItems,\n});\n</script>\n","<script>\n/*\nThis is a code from external library (https://github.com/Akryum/vue-virtual-scroller/blob/master/packages/vue-virtual-scroller/src/components/DynamicScrollerItem.vue)\nWe have modified it for our own specific use.\n*/\nimport { h } from 'vue';\nimport { returnFirstEl } from '@/common/utils';\n\nexport default {\n name: 'DtScrollerItem',\n\n inject: [\n 'vscrollData',\n 'vscrollParent',\n 'vscrollResizeObserver',\n ],\n\n props: {\n // eslint-disable-next-line vue/require-prop-types\n item: {\n required: true,\n },\n\n watchData: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Indicates if the view is actively used to display an item.\n */\n active: {\n type: Boolean,\n required: true,\n },\n\n index: {\n type: Number,\n default: undefined,\n },\n\n sizeDependencies: {\n type: [Array, Object],\n default: null,\n },\n\n tag: {\n type: String,\n default: 'div',\n },\n },\n\n computed: {\n id () {\n if (this.vscrollData.simpleArray) return this.index;\n // eslint-disable-next-line no-prototype-builtins\n if (this.vscrollData.keyField in this.item) return this.item[this.vscrollData.keyField];\n throw new Error(`keyField '${this.vscrollData.keyField}' not found in your item. You should set a valid keyField prop on your Scroller`);\n },\n\n size () {\n return this.vscrollData.sizes[this.id] || 0;\n },\n\n finalActive () {\n return this.active && this.vscrollData.active;\n },\n },\n\n watch: {\n watchData: 'updateWatchData',\n\n id (value, oldValue) {\n returnFirstEl(this.$el).$_vs_id = this.id;\n if (!this.size) {\n this.onDataUpdate();\n }\n\n if (this.$_sizeObserved) {\n // In case the old item had the same size, it won't trigger the ResizeObserver\n // since we are reusing the same DOM node\n const oldSize = this.vscrollData.sizes[oldValue];\n const size = this.vscrollData.sizes[value];\n if (oldSize != null && oldSize !== size) {\n this.applySize(oldSize);\n }\n }\n },\n\n finalActive (value) {\n if (!this.size) {\n if (value) {\n if (!this.vscrollParent.$_undefinedMap[this.id]) {\n this.vscrollParent.$_undefinedSizes++;\n this.vscrollParent.$_undefinedMap[this.id] = true;\n }\n } else {\n if (this.vscrollParent.$_undefinedMap[this.id]) {\n this.vscrollParent.$_undefinedSizes--;\n this.vscrollParent.$_undefinedMap[this.id] = false;\n }\n }\n }\n\n if (this.vscrollResizeObserver) {\n if (value) {\n this.observeSize();\n } else {\n this.unobserveSize();\n }\n } else if (value && this.$_pendingVScrollUpdate === this.id) {\n this.updateSize();\n }\n },\n },\n\n created () {\n if (this.$isServer) return;\n\n this.$_forceNextVScrollUpdate = null;\n this.updateWatchData();\n\n if (!this.vscrollResizeObserver) {\n for (const k in this.sizeDependencies) {\n this.$watch(() => this.sizeDependencies[k], this.onDataUpdate);\n }\n }\n },\n\n mounted () {\n if (this.finalActive) {\n this.updateSize();\n this.observeSize();\n }\n },\n\n beforeUnmount () {\n this.unobserveSize();\n },\n\n methods: {\n updateSize () {\n if (this.finalActive) {\n if (this.$_pendingSizeUpdate !== this.id) {\n this.$_pendingSizeUpdate = this.id;\n this.$_forceNextVScrollUpdate = null;\n this.$_pendingVScrollUpdate = null;\n this.computeSize(this.id);\n }\n } else {\n this.$_forceNextVScrollUpdate = this.id;\n }\n },\n\n updateWatchData () {\n if (this.watchData && !this.vscrollResizeObserver) {\n this.$_watchData = this.$watch('item', () => {\n this.onDataUpdate();\n }, {\n deep: true,\n });\n } else if (this.$_watchData) {\n this.$_watchData();\n this.$_watchData = null;\n }\n },\n\n onVscrollUpdate ({ force }) {\n // If not active, sechedule a size update when it becomes active\n if (!this.finalActive && force) {\n this.$_pendingVScrollUpdate = this.id;\n }\n\n if (this.$_forceNextVScrollUpdate === this.id || force || !this.size) {\n this.updateSize();\n }\n },\n\n onDataUpdate () {\n this.updateSize();\n },\n\n computeSize (id) {\n this.$nextTick(() => {\n if (this.id === id) {\n const width = returnFirstEl(this.$el).offsetWidth;\n const height = returnFirstEl(this.$el).offsetHeight;\n this.applyWidthHeight(width, height);\n }\n this.$_pendingSizeUpdate = null;\n });\n },\n\n applyWidthHeight (width, height) {\n const size = ~~(this.vscrollParent.direction === 'vertical' ? height : width);\n if (size && this.size !== size) {\n this.applySize(size);\n }\n },\n\n applySize (size) {\n if (this.vscrollParent.$_undefinedMap[this.id]) {\n this.vscrollParent.$_undefinedSizes--;\n this.vscrollParent.$_undefinedMap[this.id] = undefined;\n }\n this.vscrollData.sizes[this.id] = size;\n },\n\n observeSize () {\n if (!this.vscrollResizeObserver) return;\n if (this.$_sizeObserved) return;\n this.vscrollResizeObserver.observe(returnFirstEl(this.$el));\n this.$el.$_vs_id = this.id;\n this.$el.$_vs_onResize = this.onResize;\n this.$_sizeObserved = true;\n },\n\n unobserveSize () {\n if (!this.vscrollResizeObserver) return;\n if (!this.$_sizeObserved) return;\n this.vscrollResizeObserver.unobserve(returnFirstEl(this.$el));\n this.$el.$_vs_onResize = undefined;\n this.$_sizeObserved = false;\n },\n\n onResize (id, width, height) {\n if (this.id === id) {\n this.applyWidthHeight(width, height);\n }\n },\n },\n\n render () {\n return h(this.tag, this.$slots.default());\n },\n};\n</script>\n","<template>\n <core-scroller\n ref=\"scroller\"\n :items=\"itemsWithSize\"\n :min-item-size=\"minItemSize\"\n :direction=\"direction\"\n :key-field=\"keyField\"\n :list-tag=\"listTag\"\n :item-tag=\"itemTag\"\n v-bind=\"$attrs\"\n >\n <template\n #default=\"{ item: itemWithSize, index, active }\"\n >\n <dt-scroller-item\n :item=\"itemWithSize\"\n :active=\"active\"\n :size-dependencies=\"[\n itemWithSize.message,\n ]\"\n :data-index=\"index\"\n >\n <slot\n v-bind=\"{\n item: itemWithSize.item,\n index,\n active,\n itemWithSize,\n }\"\n />\n </dt-scroller-item>\n </template>\n </core-scroller>\n</template>\n\n<!-- eslint-disable-next-line max-len -->\n<!-- This is a code from external library (https://github.com/Akryum/vue-virtual-scroller/blob/master/packages/vue-virtual-scroller/src/components/DynamicScroller.vue)\nWe have modified it for our own specific use. -->\n<script>\nimport CoreScroller from './core_scroller.vue';\nimport DtScrollerItem from './scroller_item.vue';\nimport { returnFirstEl } from '@/common/utils';\n\nexport default {\n name: 'DynamicScroller',\n\n components: {\n CoreScroller,\n DtScrollerItem,\n },\n\n provide () {\n if (typeof ResizeObserver !== 'undefined') {\n this.$_resizeObserver = new ResizeObserver(entries => {\n requestAnimationFrame(() => {\n if (!Array.isArray(entries)) {\n return;\n }\n for (const entry of entries) {\n if (entry.target && entry.target.$_vs_onResize) {\n let width, height;\n if (entry.borderBoxSize) {\n const resizeObserverSize = entry.borderBoxSize[0];\n width = resizeObserverSize.inlineSize;\n height = resizeObserverSize.blockSize;\n } else {\n // @TODO remove when contentRect is deprecated\n width = entry.contentRect.width;\n height = entry.contentRect.height;\n }\n entry.target.$_vs_onResize(entry.target.$_vs_id, width, height);\n }\n }\n });\n });\n }\n\n return {\n vscrollData: this.vscrollData,\n vscrollParent: this,\n vscrollResizeObserver: this.$_resizeObserver,\n };\n },\n\n inheritAttrs: false,\n\n props: {\n /*\n * The items to render.\n * If the items are simple arrays, the index will be used as the key.\n * If the items are objects, the keyField will be used as the key.\n */\n items: {\n type: Array,\n required: true,\n },\n\n /*\n * Indicates if the items are dynamic.\n * If true, the items will be wrapped in a DtScrollerItem component.\n * This is required for dynamic items to be able to react to changes in their size.\n */\n dynamic: {\n type: Boolean,\n default: false,\n },\n\n /*\n * The key field to use for the items.\n * Only used if the items are objects.\n */\n keyField: {\n type: String,\n default: 'id',\n },\n\n /*\n * The direction of the scroller.\n * Can be either 'vertical' or 'horizontal'.\n */\n direction: {\n type: String,\n default: 'vertical',\n validator: (value) => ['vertical', 'horizontal'].includes(value),\n },\n\n /*\n * The tag to use for the list.\n */\n listTag: {\n type: String,\n default: 'div',\n },\n\n /*\n * The tag to use for the items.\n */\n itemTag: {\n type: String,\n default: 'div',\n },\n\n /*\n * Display height (or width in horizontal mode) of the items in pixels\n * used to calculate the scroll size and position.\n * Is required for the initial render of items in DYNAMIC size mode.\n */\n minItemSize: {\n type: [Number, String],\n },\n },\n\n data () {\n return {\n vscrollData: {\n active: true,\n sizes: {},\n keyField: this.keyField,\n simpleArray: false,\n },\n };\n },\n\n computed: {\n simpleArray () {\n return this.items.length && typeof this.items[0] !== 'object';\n },\n\n itemsWithSize () {\n const result = [];\n const { items, keyField, simpleArray } = this;\n const sizes = this.vscrollData.sizes;\n const l = items.length;\n for (let i = 0; i < l; i++) {\n const item = items[i];\n const id = simpleArray ? i : item[keyField];\n let size = sizes[id];\n if (typeof size === 'undefined' && !this.$_undefinedMap[id]) {\n size = 0;\n }\n result.push({\n item,\n [keyField]: id,\n size,\n });\n }\n return result;\n },\n },\n\n watch: {\n simpleArray: {\n handler (value) {\n this.vscrollData.simpleArray = value;\n },\n\n immediate: true,\n },\n\n itemsWithSize (next, prev) {\n const scrollTop = returnFirstEl(this.$el).scrollTop;\n\n // Calculate total diff between prev and next sizes\n // over current scroll top. Then add it to scrollTop to\n // avoid jumping the contents that the user is seeing.\n let prevActiveTop = 0; let activeTop = 0;\n const length = Math.min(next.length, prev.length);\n for (let i = 0; i < length; i++) {\n if (prevActiveTop >= scrollTop) {\n break;\n }\n prevActiveTop += prev[i].size || this.minItemSize;\n activeTop += next[i].size || this.minItemSize;\n }\n const offset = activeTop - prevActiveTop;\n\n if (offset === 0) {\n return;\n }\n\n returnFirstEl(this.$el).scrollTop += offset;\n },\n },\n\n beforeCreate () {\n this.$_updates = [];\n this.$_undefinedSizes = 0;\n this.$_undefinedMap = {};\n },\n\n activated () {\n this.vscrollData.active = true;\n },\n\n deactivated () {\n this.vscrollData.active = false;\n },\n\n methods: {\n dynamicScrollerUpdateItems () {\n const scroller = this.$refs.scroller;\n if (scroller) scroller._updateVisibleItems(true);\n },\n\n dynamicScrollerUpdateItemsFromBottom () {\n const scroller = this.$refs.scroller;\n if (scroller) scroller._updateVisibleItems(false, true);\n },\n\n scrollToItem (index) {\n const scroller = this.$refs.scroller;\n if (scroller) scroller.scrollToItem(index);\n },\n\n scrollToBottom () {\n if (this.$_scrollingToBottom) return;\n this.$_scrollingToBottom = true;\n const el = returnFirstEl(this.$el);\n // Item is inserted to the DOM\n this.$nextTick(() => {\n el.scrollTop = el.scrollHeight + 5000;\n // Item sizes are computed\n const cb = () => {\n el.scrollTop = el.scrollHeight + 5000;\n requestAnimationFrame(() => {\n el.scrollTop = el.scrollHeight + 5000;\n if (this.$_undefinedSizes === 0) {\n this.$_scrollingToBottom = false;\n } else {\n requestAnimationFrame(cb);\n }\n });\n };\n requestAnimationFrame(cb);\n });\n },\n },\n};\n</script>\n","<template>\n <component\n :is=\"dynamic ? DynamicScroller : CoreScroller\"\n ref=\"scroller\"\n data-qa=\"dt-scroller\"\n :items=\"items\"\n :item-size=\"itemSize\"\n :min-item-size=\"minItemSize\"\n :direction=\"direction\"\n :key-field=\"keyField\"\n :list-tag=\"listTag\"\n :item-tag=\"itemTag\"\n :style=\"computedStyle\"\n tabindex=\"0\"\n @user-position=\"$emit('user-position', $event)\"\n >\n <template\n #default=\"{ item, index, active }\"\n >\n <slot\n v-bind=\"{\n item: item,\n index,\n active,\n }\"\n />\n </template>\n </component>\n</template>\n\n<script setup>\nimport CoreScroller from './modules/core_scroller.vue';\nimport DynamicScroller from './modules/dynamic_scroller.vue';\nimport { provide, computed, watch, ref } from 'vue';\n\ndefineOptions({\n name: 'DtScroller',\n});\n\nconst props = defineProps({\n /**\n * The direction of the scroller.\n * @values vertical, horizontal\n */\n direction: {\n type: String,\n default: 'vertical',\n validator: (value) => ['vertical', 'horizontal'].includes(value),\n },\n\n /**\n * Indicates if the items need to react to changes in their size.\n * If disabled the itemSize prop is required and you will get improved performance.\n * If enabled the minItemSize prop is required and you\n * will have reduced performance but the ability to reactively size list items\n * @values true, false\n */\n dynamic: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Display height (or width in horizontal mode) of the items in pixels\n * used to calculate the scroll size and position.\n * Required if DYNAMIC is false\n */\n itemSize: {\n type: Number,\n default: null,\n },\n\n /**\n * The tag to use for the items.\n */\n itemTag: {\n type: String,\n default: 'div',\n },\n\n /**\n * The items to render.\n * If the items are simple arrays, the index will be used as the key.\n * If the items are objects, the keyField will be used as the key.\n * @example items: [ 'item1', 'item2', 'item3' ]\n * @example items: [ { id: 1, name: 'item1' }, { id: 2, name: 'item2' }, { id: 3, name: 'item3' } ]\n */\n items: {\n type: Array,\n required: true,\n },\n\n /**\n * The key field to use for the items.\n * If the items are objects, the scroller needs to be able to identify them.\n * By default it will look for an id field on the items.\n * This can be configured with this prop if you are using another field name.\n */\n keyField: {\n type: String,\n default: 'id',\n },\n\n /**\n * The tag to use for the list.\n */\n listTag: {\n type: String,\n default: 'div',\n },\n\n /**\n * Minimum size used if the height (or width in horizontal mode) of a item is unknown.\n * Is required for the initial render of items in DYNAMIC size mode.\n */\n minItemSize: {\n type: [Number, String],\n default: null,\n },\n\n /**\n * The height of the scroller.\n * Can be a number (in pixels) or a string (in CSS units).\n */\n scrollerHeight: {\n type: [String, Number],\n default: '100%',\n },\n\n /**\n * The width of the scroller.\n * Can be a number (in pixels) or a string (in CSS units).\n */\n scrollerWidth: {\n type: [String, Number],\n default: '100%',\n },\n});\n\nconst emits = defineEmits([\n /**\n * Describe when the scroller changes from start/middle/end\n * @param {string} position The position of the scroller.\n * @values start, middle, end\n */\n 'user-position',\n]);\n\nprovide('emit', emits);\n\nconst scroller = ref(null);\n\nconst computedStyle = computed(() => {\n return {\n width: typeof props.scrollerWidth === 'number' ? `${props.scrollerWidth}px` : props.scrollerWidth,\n height: typeof props.scrollerHeight === 'number' ? `${props.scrollerHeight}px` : props.scrollerHeight,\n };\n});\n\nwatch(props, () => {\n validateProps();\n}, { deep: true, immediate: true });\n\nfunction scrollToBottom () {\n if (scroller.value) scroller.value.scrollToBottom();\n}\n\nfunction scrollToItem (index) {\n if (scroller.value) scroller.value.scrollToItem(index);\n}\n\nfunction updateItems () {\n if (!scroller.value) return;\n if (props.dynamic) {\n scroller.value.dynamicScrollerUpdateItems();\n } else {\n scroller.value._updateVisibleItems(true);\n }\n}\n\nfunction updateItemsFromBottom () {\n if (!scroller.value) return;\n if (props.dynamic) {\n scroller.value.dynamicScrollerUpdateItemsFromBottom();\n } else {\n scroller.value._updateVisibleItems(false, true);\n }\n}\n\nfunction validateProps () {\n if (props.dynamic && !props.minItemSize) {\n console.error('scroller error: \\'minItemSize\\' is required on \\'dynamic\\' mode.');\n }\n\n if (!props.dynamic && !props.itemSize) {\n console.error('scroller error: \\'itemSize\\' is required.');\n }\n}\n\ndefineExpose({\n scrollToBottom,\n scrollToItem,\n updateItems,\n updateItemsFromBottom,\n});\n</script>\n"],"names":["props","__props","emit","__emit","views","reactive","unusedViews","pool","ref","hoverKey","ready","scroller","userPosition","endIndex","scrollDirty","lastUpdateScrollPosition","sortTimer","computedMinItemSize","totalSize","uid","sizes","computed","items","field","minItemSize","computedMinSize","accumulator","current","i","l","simpleArray","itemIndexByKey","result","watch","_updateVisibleItems","onMounted","nextTick","_addView","index","item","key","type","nr","markRaw","view","shallowReactive","_unuseView","fake","_unusedViews","unusedPool","_getScroll","isVertical","scrollState","_itemsLimitError","_sortViews","viewA","viewB","checkItem","checkPositionDiff","itemSize","keyField","count","_sizes","_views","_pool","_itemIndexByKey","_startIndex","_endIndex","_totalSize","scroll","positionDiff","_buffer","h","a","b","oldI","_a","_b","_c","_d","remainer","continuous","unusedIndex","v","_e","_f","_scrollToPosition","position","direction","viewport","scrollDirection","scrollToItem","handleScroll","container","__expose","_sfc_main","value","oldValue","returnFirstEl","oldSize","size","k","force","id","width","height","CoreScroller","DtScrollerItem","entries","entry","resizeObserverSize","next","prev","scrollTop","prevActiveTop","activeTop","length","offset","el","cb","_openBlock","_createBlock","_component_core_scroller","_mergeProps","$options","$props","_ctx","itemWithSize","active","_createVNode","_component_dt_scroller_item","_withCtx","_renderSlot","_normalizeProps","_guardReactiveProps","emits","provide","computedStyle","validateProps","scrollToBottom","updateItems","updateItemsFromBottom"],"mappings":"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"}