<!-- TODO: setting height is hacky, just make this element the scroller --> <div class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;"> {{#if $visibleItems}} {{#each $visibleItems as visibleItem @key}} <VirtualListLazyItem :component offset="{{visibleItem.offset}}" makeProps="{{makeProps}}" key="{{visibleItem.key}}" index="{{visibleItem.index}}" /> {{/each}} {{/if}} {{#if $showFooter}} <VirtualListFooter component="{{footerComponent}}"/> {{/if}} </div> <style> .virtual-list { position: relative; transition: opacity 0.25s linear; } </style> <script> import VirtualListLazyItem from './VirtualListLazyItem' import VirtualListFooter from './VirtualListFooter.html' import { virtualListStore } from './virtualListStore' import throttle from 'lodash/throttle' import { mark, stop } from '../../_utils/marks' const DISTANCE_FROM_BOTTOM_TO_FIRE = 400 const SCROLL_TO_BOTTOM_DELAY = 1000 export default { oncreate () { this.observe('showFooter', showFooter => { this.store.setForRealm({showFooter: showFooter}) }) this.observe('items', (items) => { mark('set items') this.store.setForRealm({items: items}) stop('set items') this.fireScrollToBottom = throttle(() => { this.fire('scrollToBottom') }, SCROLL_TO_BOTTOM_DELAY) }) this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => { if (allVisibleItemsHaveHeight) { this.fire('initializedVisibleItems') } }) let observedOnce = false this.observe('distanceFromBottom', (distanceFromBottom) => { if (!observedOnce) { observedOnce = true // TODO: the first time is always 0... need better way to handle this return } if (distanceFromBottom >= 0 && distanceFromBottom <= DISTANCE_FROM_BOTTOM_TO_FIRE) { this.fireScrollToBottom() } }) }, data: () => ({ component: null }), store: () => virtualListStore, components: { VirtualListLazyItem, VirtualListFooter }, computed: { distanceFromBottom: ($scrollHeight, $scrollTop, $offsetHeight) => { return $scrollHeight - $scrollTop - $offsetHeight }, // TODO: bug in svelte store, shouldn't need to do this allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight } } </script>