import { BOTTOM_SCROLL_HEIGHT, BOTTOM_TOTAL_BAR_HEIGHT } from '@/lib/constants/dom-fixed'; import { Store } from '@/lib/store'; import { debounce } from 'lodash'; import { ScrollOperator } from '@/lib/operator/ScrollOperator'; export class LayoutOperator { private bodyContainerDom: HTMLElement; private gridContainerDom: HTMLElement; private store: Store; private scrollOperator: ScrollOperator; public registerBodyContainer(bodyContainerDom: HTMLElement) { this.bodyContainerDom = bodyContainerDom; } public getBodyContainerDom() { return this.bodyContainerDom; } public registerGridContainerDom(gridContainerDom: HTMLElement) { this.gridContainerDom = gridContainerDom; } public getGridContainerDom() { return this.gridContainerDom; } constructor(store: Store, scrollOperator: ScrollOperator) { this.store = store; this.scrollOperator = scrollOperator; } public initLayoutSize(height: string | number, width: number | string, rowHeight: number) { let heightResult = height; let widthResult = width; let autoHeight = false; const { width: parentWidth, height: parentHeight } = this.gridContainerDom.getBoundingClientRect(); if (height === 'auto') { heightResult = parentHeight; autoHeight = true; } if (width === 'auto') { widthResult = parentWidth; } this.store.mutation.setTableWidthAndHeight( Number(widthResult), Number(heightResult), autoHeight, ); this.store.mutation.setRowHeight(rowHeight); } public initComponentsSize(headerGroupLevel: number) { const { height, rowHeight } = this.store.state.config; const headerHeight = rowHeight * headerGroupLevel; const bodyViewHeight = this.calculateBodyViewHeight(height, headerHeight); this.store.mutation.setHeaderHeight(headerHeight, headerGroupLevel); this.store.mutation.setBodyViewHeight(bodyViewHeight); this.flushBodyView(); } public flushBodyView() { const { rowHeight } = this.store.state.config; const rowLength = this.store.state.view.rowIndex2Id.length; const bodyHeight = rowHeight * rowLength; this.store.mutation.setBodyHeight(bodyHeight); this.scrollOperator.scrollY(this.bodyContainerDom.scrollTop); } public initResizeMonitor() { const ResizeObserver = window.ResizeObserver; const observer = new ResizeObserver(() => { const { height: oldHeight, width: oldWidth, autoHeight } = this.store.state.config; const { width, height } = this.gridContainerDom.getBoundingClientRect(); if (height === oldHeight && width === oldWidth) return; this.debounceResize(width, autoHeight ? height : oldHeight); }); observer.observe(this.gridContainerDom); } private calculateBodyViewHeight(tableHeight: number, headerHeight: number) { return tableHeight - headerHeight - BOTTOM_SCROLL_HEIGHT - BOTTOM_TOTAL_BAR_HEIGHT; } private debounceResize = debounce(function (width: number, height: number) { const newBodyViewHeight = this.calculateBodyViewHeight( height, this.store.state.config.headerHeight, ); this.store.mutation.setTableWidthAndHeight(width, height); this.store.mutation.setBodyViewHeight(newBodyViewHeight); this.scrollOperator.scrollY(this.bodyContainerDom.scrollTop); }, 100); }