forked from cybrespace/pinafore
55 lines
1.5 KiB
HTML
55 lines
1.5 KiB
HTML
<div class="virtual-list-header {{shown ? 'shown' : ''}} {{fadedIn ? 'faded-in' : ''}}"
|
|
ref:node >
|
|
<:Component {component} :virtualProps />
|
|
</div>
|
|
<style>
|
|
.virtual-list-header {
|
|
position: absolute;
|
|
top: 0;
|
|
width: 100%;
|
|
opacity: 0;
|
|
z-index: 10;
|
|
transition: none;
|
|
display: none;
|
|
}
|
|
.virtual-list-header.shown {
|
|
display: block;
|
|
transition: opacity 0.333s linear;
|
|
}
|
|
.virtual-list-header.faded-in {
|
|
opacity: 1;
|
|
}
|
|
</style>
|
|
<script>
|
|
import { virtualListStore } from './virtualListStore'
|
|
import { AsyncLayout } from '../../_utils/AsyncLayout'
|
|
import { doubleRAF } from '../../_utils/doubleRAF'
|
|
|
|
export default {
|
|
oncreate () {
|
|
this.observe('shown', shown => {
|
|
if (shown) {
|
|
this.doCalculateHeight()
|
|
doubleRAF(() => this.set({fadedIn: true})) // animate in
|
|
} else {
|
|
this.set({fadedIn: false})
|
|
}
|
|
}, {init: false})
|
|
},
|
|
store: () => virtualListStore,
|
|
methods: {
|
|
doCalculateHeight () {
|
|
let { heightCalculated } = this.get()
|
|
if (heightCalculated) { // only need to calculate once, it never changes
|
|
return
|
|
}
|
|
this.set({heightCalculated: true})
|
|
const asyncLayout = new AsyncLayout(() => '__header__')
|
|
asyncLayout.observe('__header__', this.refs.node, (rect) => {
|
|
asyncLayout.disconnect()
|
|
this.store.setForRealm({headerHeight: rect.height})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script> |