@etsoo/react 1.4.25 → 1.4.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/ScrollerList.js +1 -1
- package/lib/mu/ResponsibleContainer.d.ts +8 -0
- package/lib/mu/ResponsibleContainer.js +17 -7
- package/lib/mu/pages/DataGridPage.js +2 -1
- package/lib/mu/pages/FixedListPage.js +2 -1
- package/lib/mu/pages/ResponsivePage.js +20 -7
- package/lib/mu/pages/TablePage.js +2 -1
- package/lib/uses/useWindowSize.d.ts +6 -5
- package/lib/uses/useWindowSize.js +22 -16
- package/package.json +1 -1
- package/src/components/ScrollerList.tsx +1 -1
- package/src/mu/ResponsibleContainer.tsx +33 -6
- package/src/mu/pages/DataGridPage.tsx +2 -1
- package/src/mu/pages/FixedListPage.tsx +2 -1
- package/src/mu/pages/ResponsivePage.tsx +26 -7
- package/src/mu/pages/TablePage.tsx +3 -1
- package/src/uses/useWindowSize.ts +32 -19
|
@@ -15,7 +15,7 @@ const calculateBatchSize = (height, itemSize) => {
|
|
|
15
15
|
*/
|
|
16
16
|
export const ScrollerList = (props) => {
|
|
17
17
|
// Destruct
|
|
18
|
-
const { autoLoad = true, defaultOrderBy, defaultOrderByAsc, height =
|
|
18
|
+
const { autoLoad = true, defaultOrderBy, defaultOrderByAsc, height = document.documentElement.clientHeight, width = '100%', mRef, oRef, style = {}, itemRenderer, itemSize, loadBatchSize = calculateBatchSize(height, itemSize), loadData, threshold = GridSizeGet(loadBatchSize, height) / 2, onItemsRendered, ...rest } = props;
|
|
19
19
|
// Style
|
|
20
20
|
Object.assign(style, {
|
|
21
21
|
width: '100%',
|
|
@@ -20,6 +20,10 @@ export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.Bas
|
|
|
20
20
|
* Columns
|
|
21
21
|
*/
|
|
22
22
|
columns: GridColumn<T>[];
|
|
23
|
+
/**
|
|
24
|
+
* Container box SX (dataGrid determines the case)
|
|
25
|
+
*/
|
|
26
|
+
containerBoxSx?: (dataGrid: boolean) => SxProps<Theme>;
|
|
23
27
|
/**
|
|
24
28
|
* Min width to show Datagrid
|
|
25
29
|
*/
|
|
@@ -60,6 +64,10 @@ export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.Bas
|
|
|
60
64
|
* Methods
|
|
61
65
|
*/
|
|
62
66
|
mRef?: React.MutableRefObject<GridMethodRef | undefined>;
|
|
67
|
+
/**
|
|
68
|
+
* Element ready callback
|
|
69
|
+
*/
|
|
70
|
+
elementReady?: (element: HTMLElement, isDataGrid: boolean) => void;
|
|
63
71
|
/**
|
|
64
72
|
* Paddings
|
|
65
73
|
*/
|
|
@@ -12,8 +12,8 @@ import { SearchBar } from './SearchBar';
|
|
|
12
12
|
function getDefaultSearchBoxSx(paddings) {
|
|
13
13
|
const half = MUGlobal.half(paddings);
|
|
14
14
|
return {
|
|
15
|
-
paddingLeft:
|
|
16
|
-
paddingRight:
|
|
15
|
+
paddingLeft: (theme) => theme.spacing(0.5),
|
|
16
|
+
paddingRight: (theme) => theme.spacing(0.5),
|
|
17
17
|
paddingTop: half,
|
|
18
18
|
marginBottom: half
|
|
19
19
|
};
|
|
@@ -25,7 +25,7 @@ function getDefaultSearchBoxSx(paddings) {
|
|
|
25
25
|
*/
|
|
26
26
|
export function ResponsibleContainer(props) {
|
|
27
27
|
// Destruct
|
|
28
|
-
const { adjustHeight, columns, dataGridMinWidth = DataGridExCalColumns(columns).total, fields, fieldTemplate, height, listBoxSx, loadData, mRef, paddings = MUGlobal.pagePaddings, pullToRefresh = true, searchBoxSx = getDefaultSearchBoxSx(paddings), sizeReadyMiliseconds = 0, ...rest } = props;
|
|
28
|
+
const { adjustHeight, columns, containerBoxSx, dataGridMinWidth = DataGridExCalColumns(columns).total, elementReady, fields, fieldTemplate, height, listBoxSx, loadData, mRef, paddings = MUGlobal.pagePaddings, pullToRefresh = true, searchBoxSx = getDefaultSearchBoxSx(paddings), sizeReadyMiliseconds = 0, ...rest } = props;
|
|
29
29
|
// Labels
|
|
30
30
|
const labels = Labels.CommonPage;
|
|
31
31
|
// Refs
|
|
@@ -91,7 +91,9 @@ export function ResponsibleContainer(props) {
|
|
|
91
91
|
}
|
|
92
92
|
else {
|
|
93
93
|
// Auto calculation
|
|
94
|
-
heightLocal =
|
|
94
|
+
heightLocal =
|
|
95
|
+
document.documentElement.clientHeight -
|
|
96
|
+
Math.round(rect.bottom + 1);
|
|
95
97
|
const style = window.getComputedStyle(dimensions[0][1]);
|
|
96
98
|
const boxMargin = parseFloat(style.marginBottom);
|
|
97
99
|
if (!isNaN(boxMargin))
|
|
@@ -107,7 +109,10 @@ export function ResponsibleContainer(props) {
|
|
|
107
109
|
React.createElement(Box, { sx: listBoxSx == null
|
|
108
110
|
? undefined
|
|
109
111
|
: listBoxSx(true, heightLocal) },
|
|
110
|
-
React.createElement(DataGridEx, { autoLoad: !hasFields, height: heightLocal, width: rect.width, loadData: localLoadData, mRef: mRefs,
|
|
112
|
+
React.createElement(DataGridEx, { autoLoad: !hasFields, height: heightLocal, width: rect.width, loadData: localLoadData, mRef: mRefs, outerRef: (element) => {
|
|
113
|
+
if (element != null && elementReady)
|
|
114
|
+
elementReady(element, true);
|
|
115
|
+
}, columns: columns, ...rest })),
|
|
111
116
|
true
|
|
112
117
|
];
|
|
113
118
|
}
|
|
@@ -124,7 +129,10 @@ export function ResponsibleContainer(props) {
|
|
|
124
129
|
React.createElement(Box, { sx: listBoxSx == null
|
|
125
130
|
? undefined
|
|
126
131
|
: listBoxSx(false, heightLocal) },
|
|
127
|
-
React.createElement(ScrollerListEx, { autoLoad: !hasFields,
|
|
132
|
+
React.createElement(ScrollerListEx, { autoLoad: !hasFields, height: heightLocal, loadData: localLoadData, mRef: mRefs, oRef: (element) => {
|
|
133
|
+
if (element != null && elementReady)
|
|
134
|
+
elementReady(element, false);
|
|
135
|
+
}, ...rest })),
|
|
128
136
|
false
|
|
129
137
|
];
|
|
130
138
|
})();
|
|
@@ -140,7 +148,9 @@ export function ResponsibleContainer(props) {
|
|
|
140
148
|
? '.DataGridEx-Body'
|
|
141
149
|
: '.ScrollerListEx-Body';
|
|
142
150
|
// Layout
|
|
143
|
-
return (React.createElement(
|
|
151
|
+
return (React.createElement(Box, { sx: containerBoxSx == null || showDataGrid == null
|
|
152
|
+
? undefined
|
|
153
|
+
: containerBoxSx(showDataGrid) },
|
|
144
154
|
React.createElement(Stack, null,
|
|
145
155
|
React.createElement(Box, { ref: dimensions[0][0], sx: searchBoxSx }, searchBar),
|
|
146
156
|
list),
|
|
@@ -42,7 +42,8 @@ export function DataGridPage(props) {
|
|
|
42
42
|
const rect = dimensions[0][2];
|
|
43
43
|
React.useEffect(() => {
|
|
44
44
|
if (rect != null && rect.height > 50 && height == null) {
|
|
45
|
-
let gridHeight =
|
|
45
|
+
let gridHeight = document.documentElement.clientHeight -
|
|
46
|
+
Math.round(rect.top + rect.height + 1);
|
|
46
47
|
const style = window.getComputedStyle(dimensions[0][1]);
|
|
47
48
|
const paddingBottom = parseFloat(style.paddingBottom);
|
|
48
49
|
if (!isNaN(paddingBottom))
|
|
@@ -48,7 +48,8 @@ export function FixedListPage(props) {
|
|
|
48
48
|
const rect = dimensions[0][2];
|
|
49
49
|
const list = React.useMemo(() => {
|
|
50
50
|
if (rect != null && rect.height > 50) {
|
|
51
|
-
let height =
|
|
51
|
+
let height = document.documentElement.clientHeight -
|
|
52
|
+
Math.round(rect.top + rect.height + 1);
|
|
52
53
|
if (adjustHeight != null) {
|
|
53
54
|
height -= adjustHeight(height);
|
|
54
55
|
}
|
|
@@ -12,11 +12,13 @@ export function ResponsivePage(props) {
|
|
|
12
12
|
// Destruct
|
|
13
13
|
const { pageProps = {}, ...rest } = props;
|
|
14
14
|
(_a = pageProps.paddings) !== null && _a !== void 0 ? _a : (pageProps.paddings = MUGlobal.pagePaddings);
|
|
15
|
-
const { paddings, ...pageRest } = pageProps;
|
|
16
|
-
|
|
15
|
+
const { paddings, fabColumnDirection, ...pageRest } = pageProps;
|
|
16
|
+
// State
|
|
17
|
+
const [scrollContainer, setScrollContainer] = React.useState();
|
|
18
|
+
const [direction, setDirection] = React.useState(fabColumnDirection);
|
|
17
19
|
// Layout
|
|
18
|
-
return (React.createElement(CommonPage, { ...pageRest, paddings: {} },
|
|
19
|
-
React.createElement(ResponsibleContainer, { paddings: paddings,
|
|
20
|
+
return (React.createElement(CommonPage, { ...pageRest, paddings: {}, scrollContainer: scrollContainer, fabColumnDirection: direction },
|
|
21
|
+
React.createElement(ResponsibleContainer, { paddings: paddings, containerBoxSx: (dataGrid) => {
|
|
20
22
|
if (dataGrid) {
|
|
21
23
|
return {
|
|
22
24
|
padding: paddings
|
|
@@ -24,9 +26,20 @@ export function ResponsivePage(props) {
|
|
|
24
26
|
}
|
|
25
27
|
else {
|
|
26
28
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
paddingTop: paddings,
|
|
30
|
+
paddingBottom: paddings
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}, elementReady: (element, isDataGrid) => {
|
|
34
|
+
setDirection(!isDataGrid);
|
|
35
|
+
setScrollContainer(element);
|
|
36
|
+
}, listBoxSx: (dataGrid, height) => {
|
|
37
|
+
if (dataGrid) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return {
|
|
42
|
+
height: height
|
|
30
43
|
};
|
|
31
44
|
}
|
|
32
45
|
}, ...rest })));
|
|
@@ -51,7 +51,8 @@ export function TablePage(props) {
|
|
|
51
51
|
const rect = dimensions[0][2];
|
|
52
52
|
const list = React.useMemo(() => {
|
|
53
53
|
if (rect != null && rect.height > 50 && rect.width >= totalWidth) {
|
|
54
|
-
let maxHeight =
|
|
54
|
+
let maxHeight = document.documentElement.clientHeight -
|
|
55
|
+
(rect.top + rect.height + 1);
|
|
55
56
|
const style = window.getComputedStyle(dimensions[0][1]);
|
|
56
57
|
const paddingBottom = parseFloat(style.paddingBottom);
|
|
57
58
|
if (!isNaN(paddingBottom))
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
interface ISize {
|
|
2
|
+
width: number;
|
|
3
|
+
height: number;
|
|
4
|
+
}
|
|
1
5
|
/**
|
|
2
6
|
* Detect window size
|
|
3
|
-
* @param miliseconds Miliseconds delayed
|
|
4
7
|
* @returns Window size
|
|
5
8
|
*/
|
|
6
|
-
export declare const useWindowSize: (
|
|
7
|
-
|
|
8
|
-
height: number;
|
|
9
|
-
};
|
|
9
|
+
export declare const useWindowSize: () => ISize;
|
|
10
|
+
export {};
|
|
@@ -1,33 +1,39 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* Detect window size
|
|
4
|
-
* @param miliseconds Miliseconds delayed
|
|
5
4
|
* @returns Window size
|
|
6
5
|
*/
|
|
7
|
-
export const useWindowSize = (
|
|
6
|
+
export const useWindowSize = () => {
|
|
8
7
|
// State
|
|
9
8
|
const [size, setSize] = React.useState({
|
|
10
9
|
width: 0,
|
|
11
10
|
height: 0
|
|
12
11
|
});
|
|
13
|
-
const [state] = React.useState({});
|
|
14
|
-
const resizeHandler = () => {
|
|
15
|
-
if (state.seed != null)
|
|
16
|
-
window.clearTimeout(state.seed);
|
|
17
|
-
state.seed = window.setTimeout(() => {
|
|
18
|
-
setSize({
|
|
19
|
-
width: window.innerWidth,
|
|
20
|
-
height: window.innerHeight
|
|
21
|
-
});
|
|
22
|
-
state.seed = undefined;
|
|
23
|
-
}, miliseconds);
|
|
24
|
-
};
|
|
25
12
|
React.useEffect(() => {
|
|
13
|
+
let ticking = false;
|
|
14
|
+
let lastKnownSize;
|
|
15
|
+
let requestAnimationFrameSeed = 0;
|
|
16
|
+
const resizeHandler = () => {
|
|
17
|
+
lastKnownSize = {
|
|
18
|
+
width: document.documentElement.clientWidth,
|
|
19
|
+
height: document.documentElement.clientHeight
|
|
20
|
+
};
|
|
21
|
+
if (!ticking) {
|
|
22
|
+
requestAnimationFrameSeed = window.requestAnimationFrame(() => {
|
|
23
|
+
setSize(lastKnownSize);
|
|
24
|
+
ticking = false;
|
|
25
|
+
requestAnimationFrameSeed = 0;
|
|
26
|
+
});
|
|
27
|
+
ticking = true;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
26
30
|
window.addEventListener('resize', resizeHandler);
|
|
27
31
|
return () => {
|
|
32
|
+
// Cancel animation frame
|
|
33
|
+
if (requestAnimationFrameSeed > 0)
|
|
34
|
+
window.cancelAnimationFrame(requestAnimationFrameSeed);
|
|
35
|
+
// Remove scroll event
|
|
28
36
|
window.removeEventListener('resize', resizeHandler);
|
|
29
|
-
if (state.seed != null)
|
|
30
|
-
window.clearTimeout(state.seed);
|
|
31
37
|
};
|
|
32
38
|
}, []);
|
|
33
39
|
// Return
|
package/package.json
CHANGED
|
@@ -51,6 +51,11 @@ export interface ResponsibleContainerProps<
|
|
|
51
51
|
*/
|
|
52
52
|
columns: GridColumn<T>[];
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Container box SX (dataGrid determines the case)
|
|
56
|
+
*/
|
|
57
|
+
containerBoxSx?: (dataGrid: boolean) => SxProps<Theme>;
|
|
58
|
+
|
|
54
59
|
/**
|
|
55
60
|
* Min width to show Datagrid
|
|
56
61
|
*/
|
|
@@ -105,6 +110,11 @@ export interface ResponsibleContainerProps<
|
|
|
105
110
|
*/
|
|
106
111
|
mRef?: React.MutableRefObject<GridMethodRef | undefined>;
|
|
107
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Element ready callback
|
|
115
|
+
*/
|
|
116
|
+
elementReady?: (element: HTMLElement, isDataGrid: boolean) => void;
|
|
117
|
+
|
|
108
118
|
/**
|
|
109
119
|
* Paddings
|
|
110
120
|
*/
|
|
@@ -135,8 +145,8 @@ interface LocalRefs {
|
|
|
135
145
|
function getDefaultSearchBoxSx(paddings: {}): SxProps<Theme> {
|
|
136
146
|
const half = MUGlobal.half(paddings);
|
|
137
147
|
return {
|
|
138
|
-
paddingLeft:
|
|
139
|
-
paddingRight:
|
|
148
|
+
paddingLeft: (theme) => theme.spacing(0.5),
|
|
149
|
+
paddingRight: (theme) => theme.spacing(0.5),
|
|
140
150
|
paddingTop: half,
|
|
141
151
|
marginBottom: half
|
|
142
152
|
};
|
|
@@ -155,7 +165,9 @@ export function ResponsibleContainer<
|
|
|
155
165
|
const {
|
|
156
166
|
adjustHeight,
|
|
157
167
|
columns,
|
|
168
|
+
containerBoxSx,
|
|
158
169
|
dataGridMinWidth = DataGridExCalColumns(columns).total,
|
|
170
|
+
elementReady,
|
|
159
171
|
fields,
|
|
160
172
|
fieldTemplate,
|
|
161
173
|
height,
|
|
@@ -252,7 +264,9 @@ export function ResponsibleContainer<
|
|
|
252
264
|
heightLocal = height;
|
|
253
265
|
} else {
|
|
254
266
|
// Auto calculation
|
|
255
|
-
heightLocal =
|
|
267
|
+
heightLocal =
|
|
268
|
+
document.documentElement.clientHeight -
|
|
269
|
+
Math.round(rect.bottom + 1);
|
|
256
270
|
|
|
257
271
|
const style = window.getComputedStyle(dimensions[0][1]!);
|
|
258
272
|
const boxMargin = parseFloat(style.marginBottom);
|
|
@@ -281,6 +295,10 @@ export function ResponsibleContainer<
|
|
|
281
295
|
width={rect.width}
|
|
282
296
|
loadData={localLoadData}
|
|
283
297
|
mRef={mRefs}
|
|
298
|
+
outerRef={(element?: HTMLDivElement) => {
|
|
299
|
+
if (element != null && elementReady)
|
|
300
|
+
elementReady(element, true);
|
|
301
|
+
}}
|
|
284
302
|
columns={columns}
|
|
285
303
|
{...rest}
|
|
286
304
|
/>
|
|
@@ -309,10 +327,13 @@ export function ResponsibleContainer<
|
|
|
309
327
|
>
|
|
310
328
|
<ScrollerListEx<T>
|
|
311
329
|
autoLoad={!hasFields}
|
|
312
|
-
width={rect.width}
|
|
313
330
|
height={heightLocal}
|
|
314
331
|
loadData={localLoadData}
|
|
315
332
|
mRef={mRefs}
|
|
333
|
+
oRef={(element) => {
|
|
334
|
+
if (element != null && elementReady)
|
|
335
|
+
elementReady(element, false);
|
|
336
|
+
}}
|
|
316
337
|
{...rest}
|
|
317
338
|
/>
|
|
318
339
|
</Box>,
|
|
@@ -341,7 +362,13 @@ export function ResponsibleContainer<
|
|
|
341
362
|
|
|
342
363
|
// Layout
|
|
343
364
|
return (
|
|
344
|
-
<
|
|
365
|
+
<Box
|
|
366
|
+
sx={
|
|
367
|
+
containerBoxSx == null || showDataGrid == null
|
|
368
|
+
? undefined
|
|
369
|
+
: containerBoxSx(showDataGrid)
|
|
370
|
+
}
|
|
371
|
+
>
|
|
345
372
|
<Stack>
|
|
346
373
|
<Box ref={dimensions[0][0]} sx={searchBoxSx}>
|
|
347
374
|
{searchBar}
|
|
@@ -362,6 +389,6 @@ export function ResponsibleContainer<
|
|
|
362
389
|
}}
|
|
363
390
|
/>
|
|
364
391
|
)}
|
|
365
|
-
</
|
|
392
|
+
</Box>
|
|
366
393
|
);
|
|
367
394
|
}
|
|
@@ -75,7 +75,8 @@ export function DataGridPage<
|
|
|
75
75
|
React.useEffect(() => {
|
|
76
76
|
if (rect != null && rect.height > 50 && height == null) {
|
|
77
77
|
let gridHeight =
|
|
78
|
-
|
|
78
|
+
document.documentElement.clientHeight -
|
|
79
|
+
Math.round(rect.top + rect.height + 1);
|
|
79
80
|
|
|
80
81
|
const style = window.getComputedStyle(dimensions[0][1]!);
|
|
81
82
|
const paddingBottom = parseFloat(style.paddingBottom);
|
|
@@ -85,7 +85,8 @@ export function FixedListPage<
|
|
|
85
85
|
const list = React.useMemo(() => {
|
|
86
86
|
if (rect != null && rect.height > 50) {
|
|
87
87
|
let height =
|
|
88
|
-
|
|
88
|
+
document.documentElement.clientHeight -
|
|
89
|
+
Math.round(rect.top + rect.height + 1);
|
|
89
90
|
|
|
90
91
|
if (adjustHeight != null) {
|
|
91
92
|
height -= adjustHeight(height);
|
|
@@ -18,25 +18,44 @@ export function ResponsivePage<
|
|
|
18
18
|
const { pageProps = {}, ...rest } = props;
|
|
19
19
|
|
|
20
20
|
pageProps.paddings ??= MUGlobal.pagePaddings;
|
|
21
|
-
const { paddings, ...pageRest } = pageProps;
|
|
21
|
+
const { paddings, fabColumnDirection, ...pageRest } = pageProps;
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
// State
|
|
24
|
+
const [scrollContainer, setScrollContainer] = React.useState<HTMLElement>();
|
|
25
|
+
const [direction, setDirection] = React.useState(fabColumnDirection);
|
|
24
26
|
|
|
25
27
|
// Layout
|
|
26
28
|
return (
|
|
27
|
-
<CommonPage
|
|
29
|
+
<CommonPage
|
|
30
|
+
{...pageRest}
|
|
31
|
+
paddings={{}}
|
|
32
|
+
scrollContainer={scrollContainer}
|
|
33
|
+
fabColumnDirection={direction}
|
|
34
|
+
>
|
|
28
35
|
<ResponsibleContainer<T, F>
|
|
29
36
|
paddings={paddings}
|
|
30
|
-
|
|
37
|
+
containerBoxSx={(dataGrid) => {
|
|
31
38
|
if (dataGrid) {
|
|
32
39
|
return {
|
|
33
40
|
padding: paddings
|
|
34
41
|
};
|
|
35
42
|
} else {
|
|
36
43
|
return {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
paddingTop: paddings,
|
|
45
|
+
paddingBottom: paddings
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}}
|
|
49
|
+
elementReady={(element, isDataGrid) => {
|
|
50
|
+
setDirection(!isDataGrid);
|
|
51
|
+
setScrollContainer(element);
|
|
52
|
+
}}
|
|
53
|
+
listBoxSx={(dataGrid, height) => {
|
|
54
|
+
if (dataGrid) {
|
|
55
|
+
return {};
|
|
56
|
+
} else {
|
|
57
|
+
return {
|
|
58
|
+
height: height
|
|
40
59
|
};
|
|
41
60
|
}
|
|
42
61
|
}}
|
|
@@ -79,7 +79,9 @@ export function TablePage<
|
|
|
79
79
|
const rect = dimensions[0][2];
|
|
80
80
|
const list = React.useMemo(() => {
|
|
81
81
|
if (rect != null && rect.height > 50 && rect.width >= totalWidth) {
|
|
82
|
-
let maxHeight =
|
|
82
|
+
let maxHeight =
|
|
83
|
+
document.documentElement.clientHeight -
|
|
84
|
+
(rect.top + rect.height + 1);
|
|
83
85
|
|
|
84
86
|
const style = window.getComputedStyle(dimensions[0][1]!);
|
|
85
87
|
const paddingBottom = parseFloat(style.paddingBottom);
|
|
@@ -1,38 +1,51 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
+
interface ISize {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
/**
|
|
4
9
|
* Detect window size
|
|
5
|
-
* @param miliseconds Miliseconds delayed
|
|
6
10
|
* @returns Window size
|
|
7
11
|
*/
|
|
8
|
-
export const useWindowSize = (
|
|
12
|
+
export const useWindowSize = () => {
|
|
9
13
|
// State
|
|
10
|
-
const [size, setSize] = React.useState<{
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
}>({
|
|
14
|
+
const [size, setSize] = React.useState<ISize>({
|
|
14
15
|
width: 0,
|
|
15
16
|
height: 0
|
|
16
17
|
});
|
|
17
|
-
const [state] = React.useState<{ seed?: number }>({});
|
|
18
|
-
|
|
19
|
-
const resizeHandler = () => {
|
|
20
|
-
if (state.seed != null) window.clearTimeout(state.seed);
|
|
21
|
-
state.seed = window.setTimeout(() => {
|
|
22
|
-
setSize({
|
|
23
|
-
width: window.innerWidth,
|
|
24
|
-
height: window.innerHeight
|
|
25
|
-
});
|
|
26
|
-
state.seed = undefined;
|
|
27
|
-
}, miliseconds);
|
|
28
|
-
};
|
|
29
18
|
|
|
30
19
|
React.useEffect(() => {
|
|
20
|
+
let ticking = false;
|
|
21
|
+
let lastKnownSize: ISize;
|
|
22
|
+
let requestAnimationFrameSeed = 0;
|
|
23
|
+
|
|
24
|
+
const resizeHandler = () => {
|
|
25
|
+
lastKnownSize = {
|
|
26
|
+
width: document.documentElement.clientWidth,
|
|
27
|
+
height: document.documentElement.clientHeight
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
if (!ticking) {
|
|
31
|
+
requestAnimationFrameSeed = window.requestAnimationFrame(() => {
|
|
32
|
+
setSize(lastKnownSize);
|
|
33
|
+
ticking = false;
|
|
34
|
+
requestAnimationFrameSeed = 0;
|
|
35
|
+
});
|
|
36
|
+
ticking = true;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
31
40
|
window.addEventListener('resize', resizeHandler);
|
|
32
41
|
|
|
33
42
|
return () => {
|
|
43
|
+
// Cancel animation frame
|
|
44
|
+
if (requestAnimationFrameSeed > 0)
|
|
45
|
+
window.cancelAnimationFrame(requestAnimationFrameSeed);
|
|
46
|
+
|
|
47
|
+
// Remove scroll event
|
|
34
48
|
window.removeEventListener('resize', resizeHandler);
|
|
35
|
-
if (state.seed != null) window.clearTimeout(state.seed);
|
|
36
49
|
};
|
|
37
50
|
}, []);
|
|
38
51
|
|