@etsoo/react 1.4.22 → 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.
@@ -1,24 +1,10 @@
1
1
  import { DataTypes } from '@etsoo/shared';
2
- import { Box, Stack } from '@mui/material';
3
2
  import React from 'react';
4
- import { GridDataGet, GridLoadDataProps } from '../../components/GridLoader';
5
- import useCombinedRefs from '../../uses/useCombinedRefs';
6
- import { useDimensions } from '../../uses/useDimensions';
7
- import { DataGridEx, DataGridExCalColumns } from '../DataGridEx';
8
- import { GridMethodRef } from '../GridMethodRef';
9
3
  import { MUGlobal } from '../MUGlobal';
10
- import { ScrollerListEx } from '../ScrollerListEx';
11
- import { SearchBar } from '../SearchBar';
4
+ import { ResponsibleContainer } from '../ResponsibleContainer';
12
5
  import { CommonPage } from './CommonPage';
13
6
  import { ResponsePageProps } from './ResponsivePageProps';
14
7
 
15
- interface LocalStates {
16
- data?: FormData;
17
- element?: HTMLElement;
18
- height?: number;
19
- ref?: GridMethodRef;
20
- }
21
-
22
8
  /**
23
9
  * Fixed height list page
24
10
  * @param props Props
@@ -29,193 +15,52 @@ export function ResponsivePage<
29
15
  F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
30
16
  >(props: ResponsePageProps<T, F>) {
31
17
  // Destruct
32
- const {
33
- adjustHeight,
34
- columns,
35
- dataGridMinWidth = DataGridExCalColumns(columns).total,
36
- fields,
37
- fieldTemplate,
38
- height,
39
- loadData,
40
- innerItemRenderer,
41
- itemSize,
42
- mRef,
43
- sizeReadyMiliseconds = 0,
44
- pageProps = {},
45
- ...rest
46
- } = props;
18
+ const { pageProps = {}, ...rest } = props;
47
19
 
48
20
  pageProps.paddings ??= MUGlobal.pagePaddings;
21
+ const { paddings, fabColumnDirection, ...pageRest } = pageProps;
49
22
 
50
- // States
51
- const [states, setStates] = React.useReducer(
52
- (currentState: LocalStates, newState: Partial<LocalStates>) => {
53
- return { ...currentState, ...newState };
54
- },
55
- {
56
- height
57
- }
58
- );
59
-
60
- const localLoadData = (props: GridLoadDataProps) => {
61
- const data = GridDataGet(props, fieldTemplate);
62
- return loadData(data);
63
- };
64
-
65
- const refs = useCombinedRefs(mRef, (ref: GridMethodRef) => {
66
- if (ref == null) return;
67
- states.ref = ref;
68
- // setStates({ ref });
69
- });
70
-
71
- // On submit callback
72
- const onSubmit = (data: FormData, _reset: boolean) => {
73
- setStates({ data });
74
- };
75
-
76
- // Watch container
77
- const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
78
- const rect = dimensions[0][2];
79
- const showDataGrid = (rect?.width ?? 0) >= dataGridMinWidth;
80
-
81
- React.useEffect(() => {
82
- if (rect != null && rect.height > 50 && height == null) {
83
- let gridHeight =
84
- window.innerHeight - Math.round(rect.top + rect.height + 1);
85
-
86
- const style = window.getComputedStyle(dimensions[0][1]!);
87
- const boxPadding = parseFloat(style.paddingLeft);
88
- if (!isNaN(boxPadding)) gridHeight -= 2 * boxPadding;
89
-
90
- if (adjustHeight != null) {
91
- gridHeight -= adjustHeight(gridHeight);
92
- }
93
-
94
- if (gridHeight !== states.height) setStates({ height: gridHeight });
95
- }
96
- }, [rect]);
97
-
98
- const { paddings, ...pageRest } = pageProps;
99
-
100
- const list = React.useMemo(() => {
101
- const gridHeight = states.height;
102
- if (gridHeight == null) return;
103
-
104
- // Show in a row when under DataGrid
105
- pageProps.fabColumnDirection = !showDataGrid;
106
-
107
- if (showDataGrid) {
108
- // Delete
109
- delete rest.itemRenderer;
110
-
111
- return (
112
- <Box
113
- sx={{
114
- padding: paddings
115
- }}
116
- >
117
- <DataGridEx<T>
118
- autoLoad={false}
119
- height={gridHeight}
120
- loadData={localLoadData}
121
- mRef={refs}
122
- columns={columns}
123
- outerRef={(element?: HTMLDivElement) => {
124
- if (element != null) setStates({ element });
125
- }}
126
- {...rest}
127
- />
128
- </Box>
129
- );
130
- }
131
-
132
- // Delete
133
- delete rest.checkable;
134
- delete rest.borderRowsCount;
135
- delete rest.bottomHeight;
136
- delete rest.footerItemRenderer;
137
- delete rest.headerHeight;
138
- delete rest.hideFooter;
139
- delete rest.hoverColor;
140
- delete rest.selectable;
141
-
142
- // Half
143
- const halfPadding = MUGlobal.half(paddings);
144
- const style = window.getComputedStyle(dimensions[0][1]!);
145
- const boxPadding = parseFloat(style.paddingLeft);
146
-
147
- return (
148
- <Box
149
- sx={{
150
- height: gridHeight + (isNaN(boxPadding) ? 0 : boxPadding),
151
- paddingTop: halfPadding,
152
- paddingBottom: halfPadding
153
- }}
154
- >
155
- <ScrollerListEx<T>
156
- autoLoad={false}
157
- height={gridHeight}
158
- innerItemRenderer={innerItemRenderer}
159
- itemSize={itemSize}
160
- loadData={localLoadData}
161
- mRef={refs}
162
- oRef={(element) => {
163
- if (element != null) setStates({ element });
164
- }}
165
- {...rest}
166
- />
167
- </Box>
168
- );
169
- }, [states.height, showDataGrid, localLoadData]);
170
-
171
- const sizeRef = React.useRef<[number, number]>();
172
-
173
- const { ref, data } = states;
174
- React.useEffect(() => {
175
- if (ref == null || data == null || rect == null) return;
176
-
177
- // Resize without reset
178
- if (sizeRef.current == null) {
179
- sizeRef.current = [rect.width, rect.height];
180
- } else if (
181
- sizeRef.current[0] !== rect.width ||
182
- sizeRef.current[1] !== rect.height
183
- ) {
184
- sizeRef.current = [rect.width, rect.height];
185
- return;
186
- }
187
-
188
- ref.reset({ data });
189
- });
190
-
191
- // Pull container id
192
- const pullContainer = states.element
193
- ? showDataGrid
194
- ? '.DataGridEx-Body'
195
- : '.ScrollerListEx-Body'
196
- : undefined;
23
+ // State
24
+ const [scrollContainer, setScrollContainer] = React.useState<HTMLElement>();
25
+ const [direction, setDirection] = React.useState(fabColumnDirection);
197
26
 
198
27
  // Layout
199
28
  return (
200
29
  <CommonPage
201
30
  {...pageRest}
202
31
  paddings={{}}
203
- scrollContainer={states.element}
204
- pullContainer={pullContainer}
32
+ scrollContainer={scrollContainer}
33
+ fabColumnDirection={direction}
205
34
  >
206
- <Stack>
207
- <Box
208
- ref={dimensions[0][0]}
209
- sx={{
210
- paddingLeft: paddings,
211
- paddingTop: MUGlobal.increase(paddings, 0.5, 'xs'),
212
- paddingRight: paddings
213
- }}
214
- >
215
- <SearchBar fields={fields} onSubmit={onSubmit} />
216
- </Box>
217
- {list}
218
- </Stack>
35
+ <ResponsibleContainer<T, F>
36
+ paddings={paddings}
37
+ containerBoxSx={(dataGrid) => {
38
+ if (dataGrid) {
39
+ return {
40
+ padding: paddings
41
+ };
42
+ } else {
43
+ return {
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
59
+ };
60
+ }
61
+ }}
62
+ {...rest}
63
+ />
219
64
  </CommonPage>
220
65
  );
221
66
  }
@@ -38,4 +38,9 @@ export interface ResponsePageProps<T, F extends DataTypes.BasicTemplate>
38
38
  * Methods
39
39
  */
40
40
  mRef?: React.MutableRefObject<GridMethodRef | undefined>;
41
+
42
+ /**
43
+ * Pull to refresh data
44
+ */
45
+ pullToRefresh?: boolean;
41
46
  }
@@ -7,11 +7,7 @@ import { useDimensions } from '../../uses/useDimensions';
7
7
  import { MUGlobal } from '../MUGlobal';
8
8
  import { SearchBar } from '../SearchBar';
9
9
  import { TableEx, TableExMethodRef, TableExMinWidth } from '../TableEx';
10
- import {
11
- CommonPage,
12
- CommonPagePullContainer,
13
- CommonPageScrollContainer
14
- } from './CommonPage';
10
+ import { CommonPage, CommonPageScrollContainer } from './CommonPage';
15
11
  import { TablePageProps } from './TablePageProps';
16
12
 
17
13
  /**
@@ -83,7 +79,9 @@ export function TablePage<
83
79
  const rect = dimensions[0][2];
84
80
  const list = React.useMemo(() => {
85
81
  if (rect != null && rect.height > 50 && rect.width >= totalWidth) {
86
- let maxHeight = window.innerHeight - (rect.top + rect.height + 1);
82
+ let maxHeight =
83
+ document.documentElement.clientHeight -
84
+ (rect.top + rect.height + 1);
87
85
 
88
86
  const style = window.getComputedStyle(dimensions[0][1]!);
89
87
  const paddingBottom = parseFloat(style.paddingBottom);
@@ -104,11 +102,7 @@ export function TablePage<
104
102
 
105
103
  // Layout
106
104
  return (
107
- <CommonPage
108
- {...pageProps}
109
- scrollContainer={CommonPageScrollContainer}
110
- pullContainer={CommonPagePullContainer}
111
- >
105
+ <CommonPage {...pageProps} scrollContainer={CommonPageScrollContainer}>
112
106
  <Stack>
113
107
  <Box
114
108
  ref={dimensions[0][0]}
@@ -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