Hooks
coderljw 2024-10-13 大约 1 分钟
# 1. Antd-Table 自适应屏幕高度
import { useContext, useEffect, useRef } from 'react'
import { ConfigProvider } from 'antd'
import type { AdaptiveParams, UseAntTableAdaptiveParams } from './types'
export { AdaptiveParams, UseAntTableAdaptiveParams }
const useAntTableAdaptive = (params: UseAntTableAdaptiveParams = {}) => {
const {
minHeight = 0,
compensateHeight = 0,
screenSelector,
tableSelector = 'body',
drawer,
drawerSelector = 'body',
} = params === true ? ({} as AdaptiveParams) : params
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext)
const preWindowHeight = useRef<number>(window.innerHeight)
const preContainerHeight = useRef<number>()
const prefixCls = getPrefixCls()
const updateHeight = (screenContainer: HTMLElement, tableContainer: HTMLElement) => {
const antTableBody = tableContainer.querySelector(`.${prefixCls}-table-body`) as HTMLElement
const antTableTBody = tableContainer.querySelector(`.${prefixCls}-table-tbody`) as HTMLElement
const antTablePlaceholder = tableContainer.querySelector(
`.${prefixCls}-table-placeholder`,
) as HTMLElement
if (!antTableBody && !antTableTBody) return
const tableBodyHeight = (antTableBody || antTableTBody).offsetHeight
const containerHeight = screenContainer.scrollHeight
const windowHeight = window.innerHeight
if (containerHeight === windowHeight) return
const calcHeight = tableBodyHeight - (containerHeight - windowHeight) - compensateHeight
const height = Math.max(minHeight, calcHeight)
if (antTableBody) antTableBody.style.maxHeight = `${height}px`
if (antTablePlaceholder) antTablePlaceholder.style.height = `${height}px`
}
const getScreenContainer = (container: HTMLElement | null) => {
const screenContainer = screenSelector && document.querySelector(screenSelector)
const drawerContainer =
drawer && (container || document.body).querySelector(`.${prefixCls}-drawer-wrapper-body`)
return (screenContainer || drawerContainer || document.body) as HTMLElement
}
const modifyDrawerHeight = (container: HTMLElement | null) => {
const drawerContent = container?.querySelector(`.${prefixCls}-drawer-content`) as HTMLElement
const drawerWrapperBody = container?.querySelector(
`.${prefixCls}-drawer-wrapper-body`,
) as HTMLElement
if (drawerContent) drawerContent.style.overflow = 'unset'
if (drawerWrapperBody) drawerWrapperBody.style.height = 'auto'
}
useEffect(() => {
if (params !== true && !(typeof params === 'object' && params !== null)) return
const drawerContainer = document.querySelector(drawerSelector) as HTMLElement
const tableContainer = document.querySelector(tableSelector) as HTMLElement
const screenContainer = getScreenContainer(drawerContainer)
if (!tableContainer) return
if (drawer) modifyDrawerHeight(drawerContainer)
const ro = new ResizeObserver(([container]) => {
const offsetHeight = (container.target as HTMLElement).offsetHeight
if (offsetHeight === preContainerHeight.current) return
preContainerHeight.current = offsetHeight
updateHeight(screenContainer, tableContainer)
})
ro.observe(screenContainer)
const onresize = () => {
if (window.innerHeight === preWindowHeight.current) return
preWindowHeight.current = window.innerHeight
updateHeight(screenContainer, tableContainer)
}
window.addEventListener('resize', onresize)
return () => {
ro.unobserve(screenContainer)
window.removeEventListener('resize', onresize)
}
}, [])
}
export default useAntTableAdaptive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
- types.ts
export interface AdaptiveParams {
/**
* @name 最小高度
* @default 0
*/
minHeight?: number
/**
* @name 补偿高度
* @desc 当底部有fixed元素时使用
* @default 0
*/
compensateHeight?: number
/**
* @name 全屏包裹容器选择器
* @default body
* @example '#adaptive-screen'
*/
screenSelector?: string
/**
* @name table包裹容器选择器
* @desc 当页面中有多个Table时使用,定位Table
* @example '#adaptive-table'
*/
tableSelector?: string
/**
* @name Drawer容器
* @desc 当Table在Drawer容器中时使用,会修改drawer-wrapper-body的height为`auto`
*/
drawer?: boolean
/**
* @name drawer包裹容器选择器
* @desc 当页面中有多个Drawer时使用,定位Drawer
* @example '#adaptive-drawer'
*/
drawerSelector?: string
}
export type UseAntTableAdaptiveParams = AdaptiveParams | true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38