forked from cybrespace/pinafore
		
	
		
			
				
	
	
		
			55 lines
		
	
	
		
			No EOL
		
	
	
		
			1.7 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			No EOL
		
	
	
		
			1.7 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<div class="virtual-list-item {{shown ? 'shown' : ''}}"
 | 
						|
     virtual-list-key="{{key}}"
 | 
						|
     ref:node
 | 
						|
     style="transform: translateY({{offset}}px);" >
 | 
						|
  <:Component {component} virtualProps="{{props}}" virtualIndex="{{index}}" virtualLength="{{$numItems}}"
 | 
						|
              on:recalculateHeight="doRecalculateHeight()"/>
 | 
						|
</div>
 | 
						|
<style>
 | 
						|
  .virtual-list-item {
 | 
						|
    position: absolute;
 | 
						|
    top: 0;
 | 
						|
    opacity: 0;
 | 
						|
    pointer-events: none;
 | 
						|
  }
 | 
						|
  .virtual-list-item.shown {
 | 
						|
    opacity: 1;
 | 
						|
    pointer-events: auto;
 | 
						|
  }
 | 
						|
</style>
 | 
						|
<script>
 | 
						|
  import { virtualListStore } from '../_utils/virtualListStore'
 | 
						|
  import { AsyncLayout } from '../_utils/AsyncLayout'
 | 
						|
 | 
						|
  const keyGetter = node => node.getAttribute('virtual-list-key')
 | 
						|
  const asyncLayout = new AsyncLayout(keyGetter)
 | 
						|
 | 
						|
  export default {
 | 
						|
    oncreate() {
 | 
						|
      let key = this.get('key')
 | 
						|
      asyncLayout.observe(key, this.refs.node, (rect) => {
 | 
						|
        // update all item heights in one microtask batch for better perf
 | 
						|
        this.store.batchUpdate('itemHeights', key, rect.height)
 | 
						|
      })
 | 
						|
    },
 | 
						|
    ondestroy() {
 | 
						|
      let key = this.get('key')
 | 
						|
      asyncLayout.unobserve(key, this.refs.node)
 | 
						|
    },
 | 
						|
    store: () => virtualListStore,
 | 
						|
    computed: {
 | 
						|
      'shown': ($itemHeights, key) => $itemHeights[key] > 0
 | 
						|
    },
 | 
						|
    methods: {
 | 
						|
      doRecalculateHeight() {
 | 
						|
        let tempAsyncLayout = new AsyncLayout(keyGetter)
 | 
						|
        let key = this.get('key')
 | 
						|
        tempAsyncLayout.observe(key, this.refs.node, (rect) => {
 | 
						|
          tempAsyncLayout.disconnect()
 | 
						|
          // update all item heights in one microtask batch for better perf
 | 
						|
          this.store.batchUpdate('itemHeights', key, rect.height)
 | 
						|
        })
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
</script> |