@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.
@@ -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 = window.innerHeight, width = '100%', mRef, oRef, style = {}, itemRenderer, itemSize, loadBatchSize = calculateBatchSize(height, itemSize), loadData, threshold = GridSizeGet(loadBatchSize, height) / 2, onItemsRendered, ...rest } = props;
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: half,
16
- paddingRight: half,
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 = window.innerHeight - Math.round(rect.bottom + 1);
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, columns: columns, ...rest })),
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, width: rect.width, height: heightLocal, loadData: localLoadData, mRef: mRefs, ...rest })),
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(React.Fragment, null,
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 = window.innerHeight - Math.round(rect.top + rect.height + 1);
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 = window.innerHeight - Math.round(rect.top + rect.height + 1);
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
- const halfPadding = MUGlobal.half(paddings);
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, listBoxSx: (dataGrid, height) => {
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
- height,
28
- paddingTop: halfPadding,
29
- paddingBottom: halfPadding
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 = window.innerHeight - (rect.top + rect.height + 1);
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: (miliseconds?: number) => {
7
- width: number;
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 = (miliseconds = 50) => {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.4.25",
3
+ "version": "1.4.26",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -106,7 +106,7 @@ export const ScrollerList = <T extends Record<string, any>>(
106
106
  autoLoad = true,
107
107
  defaultOrderBy,
108
108
  defaultOrderByAsc,
109
- height = window.innerHeight,
109
+ height = document.documentElement.clientHeight,
110
110
  width = '100%',
111
111
  mRef,
112
112
  oRef,
@@ -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: half,
139
- paddingRight: half,
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 = window.innerHeight - Math.round(rect.bottom + 1);
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
- <React.Fragment>
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
- </React.Fragment>
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
- window.innerHeight - Math.round(rect.top + rect.height + 1);
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
- window.innerHeight - Math.round(rect.top + rect.height + 1);
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
- const halfPadding = MUGlobal.half(paddings);
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 {...pageRest} paddings={{}}>
29
+ <CommonPage
30
+ {...pageRest}
31
+ paddings={{}}
32
+ scrollContainer={scrollContainer}
33
+ fabColumnDirection={direction}
34
+ >
28
35
  <ResponsibleContainer<T, F>
29
36
  paddings={paddings}
30
- listBoxSx={(dataGrid, height) => {
37
+ containerBoxSx={(dataGrid) => {
31
38
  if (dataGrid) {
32
39
  return {
33
40
  padding: paddings
34
41
  };
35
42
  } else {
36
43
  return {
37
- height,
38
- paddingTop: halfPadding,
39
- paddingBottom: halfPadding
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 = window.innerHeight - (rect.top + rect.height + 1);
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 = (miliseconds: number = 50) => {
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