-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
GridBody.tsx
115 lines (102 loc) · 4.48 KB
/
GridBody.tsx
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import * as React from 'react';
import PropTypes from 'prop-types';
import { GridEvents } from '../../models/events';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
import { ElementSize } from '../../models/elementSize';
import { GridMainContainer } from '../containers/GridMainContainer';
import { GridAutoSizer } from '../GridAutoSizer';
import { GridOverlays } from './GridOverlays';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { gridDensityHeaderHeightSelector } from '../../hooks/features/density/densitySelector';
interface GridBodyProps {
children?: React.ReactNode;
VirtualScrollerComponent: React.JSXElementConstructor<
React.HTMLAttributes<HTMLDivElement> & {
ref: React.Ref<HTMLDivElement>;
disableVirtualization: boolean;
}
>;
ColumnHeadersComponent: React.JSXElementConstructor<
React.HTMLAttributes<HTMLDivElement> & {
ref: React.Ref<HTMLDivElement>;
innerRef: React.Ref<HTMLDivElement>;
}
>;
}
function GridBody(props: GridBodyProps) {
const { children, VirtualScrollerComponent, ColumnHeadersComponent } = props;
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
const headerHeight = useGridSelector(apiRef, gridDensityHeaderHeightSelector);
const [isVirtualizationDisabled, setIsVirtualizationDisabled] = React.useState(
rootProps.disableVirtualization,
);
const disableVirtualization = React.useCallback(() => {
setIsVirtualizationDisabled(true);
}, []);
const enableVirtualization = React.useCallback(() => {
setIsVirtualizationDisabled(false);
}, []);
// The `useGridApiMethod` hook can't be used here, because it only installs the
// method if it doesn't exist yet. Once installed, it's never updated again.
// This break the methods above, since their closure comes from the first time
// they were installed. Which means that calling `setIsVirtualizationDisabled`
// will trigger a re-render, but it won't update the state. That can be solved
// by migrating the virtualization status to the global state.
apiRef.current.unstable_disableVirtualization = disableVirtualization;
apiRef.current.unstable_enableVirtualization = enableVirtualization;
const columnHeadersRef = React.useRef<HTMLDivElement>(null);
const columnsContainerRef = React.useRef<HTMLDivElement>(null);
const windowRef = React.useRef<HTMLDivElement>(null);
const renderingZoneRef = React.useRef<HTMLDivElement>(null);
apiRef.current.columnHeadersContainerElementRef = columnsContainerRef;
apiRef.current.columnHeadersElementRef = columnHeadersRef;
apiRef.current.windowRef = windowRef; // TODO rename, it's not attached to the window anymore
apiRef.current.renderingZoneRef = renderingZoneRef; // TODO remove, nobody should have access to internal parts of the virtualization
const handleResize = React.useCallback(
(size: ElementSize) => {
apiRef.current.publishEvent(GridEvents.resize, size);
},
[apiRef],
);
return (
<GridMainContainer>
<GridOverlays />
<ColumnHeadersComponent ref={columnsContainerRef} innerRef={columnHeadersRef} />
<GridAutoSizer
nonce={rootProps.nonce}
disableHeight={rootProps.autoHeight}
onResize={handleResize}
>
{(size: { height?: number; width: number }) => {
const style = {
width: size.width,
// If `autoHeight` is on, there will be no height value.
// In this case, let the container to grow whatever it needs.
height: size.height ? size.height - headerHeight : 'auto',
marginTop: headerHeight,
} as React.CSSProperties;
return (
<VirtualScrollerComponent
ref={windowRef}
style={style}
disableVirtualization={isVirtualizationDisabled}
/>
);
}}
</GridAutoSizer>
{children}
</GridMainContainer>
);
}
GridBody.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
children: PropTypes.node,
ColumnHeadersComponent: PropTypes.elementType.isRequired,
VirtualScrollerComponent: PropTypes.elementType.isRequired,
} as any;
export { GridBody };