Skip to content

Commit dc5cf9a

Browse files
committed
feat: dynamically resize grid to match window height
1 parent 63e017a commit dc5cf9a

File tree

1 file changed

+70
-25
lines changed
  • electron/renderer/components/grid

1 file changed

+70
-25
lines changed

electron/renderer/components/grid/grid.tsx

+70-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { EuiText, useEuiTheme } from '@elastic/eui';
22
import { css } from '@emotion/react';
3-
import { Ref, createRef, useMemo, useRef, useState } from 'react';
3+
import { Ref, createRef, useEffect, useMemo, useRef, useState } from 'react';
44
import { Layout, Responsive, WidthProvider } from 'react-grid-layout';
55
import { GridItem } from '../grid-item';
66
import { useLogger } from '../logger';
@@ -10,28 +10,39 @@ const Grid: React.FC = (): JSX.Element => {
1010

1111
const { euiTheme } = useEuiTheme();
1212

13-
const gridLayoutStyles = css`
14-
.react-grid-item.react-grid-placeholder {
15-
${css({
16-
background: euiTheme.colors.warning,
17-
})}
18-
}
19-
.react-grid-item .grab-handle {
20-
${css({
21-
cursor: 'grab',
22-
})}
23-
}
24-
.react-grid-item .grab-handle:active {
13+
const [gridLayoutStyles, setGridLayoutStyles] = useState(css``);
14+
15+
useEffect(() => {
16+
setGridLayoutStyles(css`
2517
${css({
26-
cursor: 'grabbing',
18+
height: window.innerHeight,
19+
minHeight: window.innerHeight,
20+
maxHeight: window.innerHeight,
2721
})}
28-
}
29-
`;
22+
.react-grid-item.react-grid-placeholder {
23+
${css({
24+
background: euiTheme.colors.warning,
25+
})}
26+
}
27+
.react-grid-item .grab-handle {
28+
${css({
29+
cursor: 'grab',
30+
})}
31+
}
32+
.react-grid-item .grab-handle:active {
33+
${css({
34+
cursor: 'grabbing',
35+
})}
36+
}
37+
`);
38+
}, [window?.innerHeight]);
3039

3140
const gridItemTextStyles = css({
3241
fontFamily: euiTheme.font.familyCode,
3342
fontSize: euiTheme.size.m,
3443
lineHeight: 'initial',
44+
paddingLeft: euiTheme.size.s,
45+
paddingRight: euiTheme.size.s,
3546
});
3647

3748
/**
@@ -44,6 +55,32 @@ const Grid: React.FC = (): JSX.Element => {
4455
return WidthProvider(Responsive);
4556
}, []);
4657

58+
/**
59+
* When resize horizontally or vertically, this is the number
60+
* of pixels the grid item will grow or shrink per increment.
61+
* Use smaller numbers to give users more granular and precise control.
62+
* Use larger numbers to give users more coarse and quick control.
63+
*/
64+
const resizeMaxColumns = 50; // increment = divide page width by this value
65+
const resizeRowHeightIncrement = 10; // approx. pixels to change vertically
66+
const gridItemMargin = 1.03; // pixels, when grid layout margin is [1, 1]
67+
const rowHeightWithMargin = resizeRowHeightIncrement + gridItemMargin;
68+
69+
const [gridMaxRows, setGridMaxRows] = useState<number>(10);
70+
71+
// Recalculate the max grid layout height when the window is resized.
72+
// This lets the user drag the grid items around the whole window.
73+
// https://stackoverflow.com/questions/36862334/get-viewport-window-height-in-reactjs
74+
useEffect(() => {
75+
const onWindowResize = () => {
76+
setGridMaxRows(Math.floor(window.innerHeight / rowHeightWithMargin));
77+
};
78+
window.addEventListener('resize', onWindowResize);
79+
return () => {
80+
window.removeEventListener('resize', onWindowResize);
81+
};
82+
}, []);
83+
4784
/**
4885
* Define the initial layout state.
4986
*
@@ -65,6 +102,8 @@ const Grid: React.FC = (): JSX.Element => {
65102
{ i: 'c', x: 9, y: 0, w: 6, minW: 5, h: 10, minH: 2, title: 'Combat' },
66103
]);
67104

105+
const lastLayoutThatRespectsMaxHeight = useRef<Array<Layout>>([]);
106+
68107
/**
69108
* Originally I called `useRef` in the `children` `useMemo` hook below but
70109
* that caused "Error: Rendered fewer hooks than expected" to be thrown.
@@ -100,22 +139,28 @@ const Grid: React.FC = (): JSX.Element => {
100139
});
101140
}, [layout.length]);
102141

103-
/**
104-
* When resize horizontally or vertically, this is the number
105-
* of pixels the grid item will grow or shrink per increment.
106-
* Use smaller numbers to give users more granular and precise control.
107-
* Use larger numbers to give users more coarse and quick control.
108-
*/
109-
const resizeMaxColumns = 50; // increment = divide page width by this value
110-
const resizeRowHeightIncrement = 10; // approx. pixels to change vertically
111-
112142
return (
113143
<ResponsiveGridLayout
114144
css={gridLayoutStyles}
115145
layouts={{ lg: layout }}
116146
breakpoints={{ lg: 1200 }}
117147
cols={{ lg: resizeMaxColumns }}
118148
rowHeight={resizeRowHeightIncrement}
149+
maxRows={gridMaxRows}
150+
autoSize={false}
151+
margin={[1, 1]}
152+
onLayoutChange={(layout) => {
153+
// const isTooTall = layout.some((item) => {
154+
// return false;
155+
// });
156+
}}
157+
onDragStart={(layout) => {
158+
lastLayoutThatRespectsMaxHeight.current = layout;
159+
}}
160+
onResizeStart={(layout) => {
161+
lastLayoutThatRespectsMaxHeight.current = layout;
162+
}}
163+
compactType={null}
119164
isBounded={true}
120165
isDraggable={true}
121166
isDroppable={true}

0 commit comments

Comments
 (0)