|
@@ -1,8 +1,9 @@
|
|
|
-import { useState, useEffect } from 'react'
|
|
|
|
|
|
|
+import { useState, useEffect, useMemo, useLayoutEffect, useRef } from 'react'
|
|
|
import { useDebounceFn } from 'ahooks'
|
|
import { useDebounceFn } from 'ahooks'
|
|
|
import { useStore } from 'dva'
|
|
import { useStore } from 'dva'
|
|
|
|
|
+import { getViewportOffset } from '@/utils/domUtils'
|
|
|
|
|
+import { useWindowSizeFn } from './event/useWindomSizeFn'
|
|
|
/**
|
|
/**
|
|
|
- *
|
|
|
|
|
* @param {number} needSubtractHeight 被裁去的高度
|
|
* @param {number} needSubtractHeight 被裁去的高度
|
|
|
* @param {number} needSubtractWidth 被裁去的宽度
|
|
* @param {number} needSubtractWidth 被裁去的宽度
|
|
|
*/
|
|
*/
|
|
@@ -36,3 +37,121 @@ const useAutoTable = (needSubtractHeight, needSubtractWidth) => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export default useAutoTable
|
|
export default useAutoTable
|
|
|
|
|
+
|
|
|
|
|
+export function useTableScroll(columnsRef, selectKeysRef) {
|
|
|
|
|
+ let paginationEl = null
|
|
|
|
|
+ let footerEl = null
|
|
|
|
|
+ let bodyEl = null
|
|
|
|
|
+ const [tableHeight, setTableHeight] = useState(null)
|
|
|
|
|
+
|
|
|
|
|
+ // const toolbarEl = null
|
|
|
|
|
+ async function calcTableHeight() {
|
|
|
|
|
+ const tableEl = document.getElementsByClassName('ant-pro-table')[0]
|
|
|
|
|
+ if (!tableEl) return
|
|
|
|
|
+
|
|
|
|
|
+ if (!bodyEl) {
|
|
|
|
|
+ bodyEl = tableEl.querySelector('.ant-table-tbody')
|
|
|
|
|
+ bodyEl && (bodyEl.style.height = 'unset')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight
|
|
|
|
|
+
|
|
|
|
|
+ const headEl = tableEl.querySelector('.ant-table-thead ')
|
|
|
|
|
+
|
|
|
|
|
+ if (!headEl) return
|
|
|
|
|
+ // Table height from bottom
|
|
|
|
|
+ const { bottomIncludeBody } = getViewportOffset(headEl)
|
|
|
|
|
+
|
|
|
|
|
+ const paddingHeight = 32
|
|
|
|
|
+
|
|
|
|
|
+ // Pager height
|
|
|
|
|
+ let paginationHeight = 2
|
|
|
|
|
+
|
|
|
|
|
+ if (!paginationEl) {
|
|
|
|
|
+ paginationEl = tableEl.querySelector('.ant-pagination')
|
|
|
|
|
+ if (paginationEl) {
|
|
|
|
|
+ const { offsetHeight } = paginationEl
|
|
|
|
|
+ paginationHeight += offsetHeight || 0
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // TODO First fix 24
|
|
|
|
|
+ paginationHeight += 24
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ paginationHeight = -8
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let footerHeight = 0
|
|
|
|
|
+ if (!paginationEl) {
|
|
|
|
|
+ if (!footerEl) {
|
|
|
|
|
+ footerEl = tableEl.querySelector('.ant-table-footer')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const { offsetHeight } = footerEl
|
|
|
|
|
+ footerHeight += offsetHeight || 0
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let headerHeight = 0
|
|
|
|
|
+ if (headEl) {
|
|
|
|
|
+ headerHeight = headEl.offsetHeight
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const height =
|
|
|
|
|
+ bottomIncludeBody - paddingHeight - paginationHeight - footerHeight - headerHeight
|
|
|
|
|
+
|
|
|
|
|
+ console.log('bottomIncludeBody', bottomIncludeBody)
|
|
|
|
|
+ console.log('paddingHeight', paddingHeight)
|
|
|
|
|
+ console.log('paginationHeight', paginationHeight)
|
|
|
|
|
+ console.log('footerHeight', footerHeight)
|
|
|
|
|
+ console.log('headerHeight', headerHeight)
|
|
|
|
|
+ setTableHeight(height)
|
|
|
|
|
+ bodyEl && (bodyEl.style.height = `${height}px`)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function redoHeight() {
|
|
|
|
|
+ calcTableHeight()
|
|
|
|
|
+ }
|
|
|
|
|
+ const { run: debounceRedoHeight } = useDebounceFn(redoHeight, { wait: 100 })
|
|
|
|
|
+
|
|
|
|
|
+ // Greater than animation time 280
|
|
|
|
|
+ useWindowSizeFn(calcTableHeight, 280)
|
|
|
|
|
+
|
|
|
|
|
+ useLayoutEffect(() => {
|
|
|
|
|
+ debounceRedoHeight()
|
|
|
|
|
+ }, [])
|
|
|
|
|
+
|
|
|
|
|
+ useLayoutEffect(() => {
|
|
|
|
|
+ debounceRedoHeight()
|
|
|
|
|
+ }, [selectKeysRef.length])
|
|
|
|
|
+
|
|
|
|
|
+ const getSrollX = useMemo(() => {
|
|
|
|
|
+ let width = 0
|
|
|
|
|
+ if (selectKeysRef.length) {
|
|
|
|
|
+ width += 60
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // TODO props ?? 0;
|
|
|
|
|
+ const NORMAL_WIDTH = 150
|
|
|
|
|
+
|
|
|
|
|
+ const columns = columnsRef.filter(item => !item.defaultHidden)
|
|
|
|
|
+ columns.forEach(item => {
|
|
|
|
|
+ width += Number.parseInt(item.width) || 0
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ const unsetWidthColumns = columns.filter(item => !Reflect.has(item, 'width'))
|
|
|
|
|
+
|
|
|
|
|
+ const len = unsetWidthColumns.length
|
|
|
|
|
+ if (len !== 0) {
|
|
|
|
|
+ width += len * NORMAL_WIDTH
|
|
|
|
|
+ }
|
|
|
|
|
+ const tableEl = document.getElementsByClassName('ant-pro-table')[0]
|
|
|
|
|
+
|
|
|
|
|
+ const tableWidth = tableEl && tableEl.offsetWidth ? tableEl.offsetWidth : 0
|
|
|
|
|
+
|
|
|
|
|
+ return tableWidth > width ? '100%' : width
|
|
|
|
|
+ }, [selectKeysRef])
|
|
|
|
|
+
|
|
|
|
|
+ const getScrollRef = useMemo(() => {
|
|
|
|
|
+ return { x: getSrollX, y: tableHeight || null }
|
|
|
|
|
+ }, [getSrollX, tableHeight])
|
|
|
|
|
+ return { getScrollRef, redoHeight }
|
|
|
|
|
+}
|