1
1
import { EuiText , useEuiTheme } from '@elastic/eui' ;
2
2
import { css } from '@emotion/react' ;
3
- import { Ref , createRef , useMemo , useRef , useState } from 'react' ;
3
+ import { Ref , createRef , useEffect , useMemo , useRef , useState } from 'react' ;
4
4
import { Layout , Responsive , WidthProvider } from 'react-grid-layout' ;
5
5
import { GridItem } from '../grid-item' ;
6
6
import { useLogger } from '../logger' ;
@@ -10,28 +10,39 @@ const Grid: React.FC = (): JSX.Element => {
10
10
11
11
const { euiTheme } = useEuiTheme ( ) ;
12
12
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 `
25
17
${ css ( {
26
- cursor : 'grabbing' ,
18
+ height : window . innerHeight ,
19
+ minHeight : window . innerHeight ,
20
+ maxHeight : window . innerHeight ,
27
21
} ) }
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 ] ) ;
30
39
31
40
const gridItemTextStyles = css ( {
32
41
fontFamily : euiTheme . font . familyCode ,
33
42
fontSize : euiTheme . size . m ,
34
43
lineHeight : 'initial' ,
44
+ paddingLeft : euiTheme . size . s ,
45
+ paddingRight : euiTheme . size . s ,
35
46
} ) ;
36
47
37
48
/**
@@ -44,6 +55,32 @@ const Grid: React.FC = (): JSX.Element => {
44
55
return WidthProvider ( Responsive ) ;
45
56
} , [ ] ) ;
46
57
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
+
47
84
/**
48
85
* Define the initial layout state.
49
86
*
@@ -65,6 +102,8 @@ const Grid: React.FC = (): JSX.Element => {
65
102
{ i : 'c' , x : 9 , y : 0 , w : 6 , minW : 5 , h : 10 , minH : 2 , title : 'Combat' } ,
66
103
] ) ;
67
104
105
+ const lastLayoutThatRespectsMaxHeight = useRef < Array < Layout > > ( [ ] ) ;
106
+
68
107
/**
69
108
* Originally I called `useRef` in the `children` `useMemo` hook below but
70
109
* that caused "Error: Rendered fewer hooks than expected" to be thrown.
@@ -100,22 +139,28 @@ const Grid: React.FC = (): JSX.Element => {
100
139
} ) ;
101
140
} , [ layout . length ] ) ;
102
141
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
-
112
142
return (
113
143
< ResponsiveGridLayout
114
144
css = { gridLayoutStyles }
115
145
layouts = { { lg : layout } }
116
146
breakpoints = { { lg : 1200 } }
117
147
cols = { { lg : resizeMaxColumns } }
118
148
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 }
119
164
isBounded = { true }
120
165
isDraggable = { true }
121
166
isDroppable = { true }
0 commit comments