import { useState, useEffect, useMemo, useLayoutEffect, useRef } from 'react' import { useDebounceFn, useMount, useUpdateLayoutEffect } from 'ahooks' import { useStore } from 'dva' import { getViewportOffset } from '@/utils/domUtils' import { useWindowSizeFn } from './event/useWindomSizeFn' /** * @param {number} needSubtractHeight 被裁去的高度 * @param {number} needSubtractWidth 被裁去的宽度 */ const useAutoTable = (needSubtractHeight, needSubtractWidth) => { const { collapsed = true } = useStore().getState().global const [scroll, setScroll] = useState({ x: document.body.clientWidth - ((collapsed ? 208 : 48) + needSubtractWidth), y: document.body.clientHeight - needSubtractHeight }) // const { run, cancel } = useDebounceFn(handleScroll, { wait: 5000}) const { run, cancel } = useDebounceFn(() => setScroll({ ...scroll, x: document.body.clientWidth - ((collapsed ? 208 : 48) + needSubtractWidth), y: document.body.clientHeight - needSubtractHeight }) ) useEffect(() => { run() return () => cancel() }, [collapsed]) useEffect(() => { window.addEventListener('resize', run) return () => { window.removeEventListener('resize', cancel) } }, []) // 实际返回的宽度要大一点让table出现滚动条,反正折叠菜单栏卡顿 return [scroll.x + 50, scroll.y] } export default useAutoTable export function useTableScroll(columnsRef, selectKeysRef) { let paginationEl = null let footerEl = null let bodyEl = null const [tableHeight, setTableHeight] = useState(null) async function calcTableHeight() { const tableEl = document.getElementsByClassName('ant-table-wrapper')[0] if (!tableEl) return if (!bodyEl) { bodyEl = tableEl.querySelector('.ant-table-body') 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 = 64 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 setTableHeight(height) bodyEl && (bodyEl.style.height = `${height}px`) } function redoHeight() { calcTableHeight() } const { run: debounceRedoHeight } = useDebounceFn(redoHeight, { wait: 280 }) // Greater than animation time 280 useWindowSizeFn(calcTableHeight, 280) useMount(() => { debounceRedoHeight() }) useUpdateLayoutEffect(() => { 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 } }