53 lines
1.9 KiB
JavaScript
53 lines
1.9 KiB
JavaScript
import { Component, NewState, Util, RefreshState } from '@web/state'
|
|
import { VirtualScroll } from '@web/base'
|
|
|
|
Component.register('DataTable', container => {
|
|
const vs = VirtualScroll()
|
|
if (!container.state) container.state = NewState({})
|
|
const state = container.state
|
|
|
|
Object.assign(state, {
|
|
list: [], _renderedList: [],
|
|
prevHeight: 0, postHeight: 0, _listStartIndex: 0,
|
|
perf: { refreshTime: 0, refreshCount: 0, scrollCount: 0, totalNodes: 0 }
|
|
})
|
|
|
|
container.refresh = () => {
|
|
const start = performance.now()
|
|
const res = vs.calc(container, state.list)
|
|
if (res) {
|
|
state.perf.refreshCount++
|
|
Object.assign(state, {
|
|
prevHeight: res.prevHeight, postHeight: res.postHeight,
|
|
_listStartIndex: res.listStartIndex, _renderedList: res.renderedList
|
|
})
|
|
state.perf.refreshTime += (performance.now() - start)
|
|
state.perf.totalNodes += res.renderedList.length
|
|
}
|
|
}
|
|
|
|
container.onItemUpdate = (index, node) => vs.update(index + (state._listStartIndex || 0), node)
|
|
|
|
state.__watch('list', list => {
|
|
state._listStartIndex = 0
|
|
state._renderedList = vs.reset(list, container) || []
|
|
setTimeout(() => { if (state.list === list) vs.init(list, container.refresh) })
|
|
})
|
|
|
|
container.onScroll = () => {
|
|
state.perf.scrollCount++
|
|
container.refresh()
|
|
}
|
|
|
|
}, Util.makeDom(/*html*/`
|
|
<div class="dt-root h-100 overflow-auto" onscroll="this.onScroll()" style="overflow-anchor:none; display: block">
|
|
<div $if="(this.state?.prevHeight || 0) > 0" $style="'height:' + this.state.prevHeight + 'px;'" class="flex-shrink-0"></div>
|
|
<div $each="this.state?._renderedList" class="dt-row border-bottom d-flex align-items-center px-2" style="height:40px; flex-shrink:0" $onupdate="this.onItemUpdate(index, thisNode)">
|
|
<span $text="item.label || item.id"></span>
|
|
</div>
|
|
<div $if="(this.state?.postHeight || 0) > 0" $style="'height:' + this.state.postHeight + 'px;'" class="flex-shrink-0"></div>
|
|
</div>
|
|
`))
|
|
|
|
if (typeof document !== 'undefined') RefreshState(document.documentElement)
|