@etsoo/react 1.4.23 → 1.4.27
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 +3 -1
- package/lib/mu/DataGridEx.js +2 -2
- package/lib/mu/DataGridRenderers.js +11 -9
- package/lib/mu/ResponsibleContainer.d.ts +9 -1
- package/lib/mu/ResponsibleContainer.js +42 -13
- package/lib/mu/SearchBar.js +28 -26
- package/lib/mu/pages/CommonPage.d.ts +0 -4
- package/lib/mu/pages/CommonPage.js +2 -11
- package/lib/mu/pages/CommonPageProps.d.ts +0 -4
- package/lib/mu/pages/DataGridPage.js +4 -7
- package/lib/mu/pages/FixedListPage.js +3 -6
- package/lib/mu/pages/ListPage.js +2 -2
- package/lib/mu/pages/ResponsivePage.js +33 -119
- package/lib/mu/pages/ResponsivePageProps.d.ts +4 -0
- package/lib/mu/pages/TablePage.js +4 -3
- 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 +4 -1
- package/src/mu/DataGridEx.tsx +2 -2
- package/src/mu/DataGridRenderers.tsx +10 -10
- package/src/mu/ResponsibleContainer.tsx +76 -16
- package/src/mu/SearchBar.tsx +25 -23
- package/src/mu/pages/CommonPage.tsx +0 -21
- package/src/mu/pages/CommonPageProps.ts +0 -5
- package/src/mu/pages/DataGridPage.tsx +3 -11
- package/src/mu/pages/FixedListPage.tsx +2 -7
- package/src/mu/pages/ListPage.tsx +2 -10
- package/src/mu/pages/ResponsivePage.tsx +37 -192
- package/src/mu/pages/ResponsivePageProps.ts +5 -0
- package/src/mu/pages/TablePage.tsx +5 -11
- package/src/uses/useWindowSize.ts +32 -19
|
@@ -6,7 +6,7 @@ import { useDimensions } from '../../uses/useDimensions';
|
|
|
6
6
|
import { MUGlobal } from '../MUGlobal';
|
|
7
7
|
import { SearchBar } from '../SearchBar';
|
|
8
8
|
import { TableEx, TableExMinWidth } from '../TableEx';
|
|
9
|
-
import { CommonPage,
|
|
9
|
+
import { CommonPage, CommonPageScrollContainer } from './CommonPage';
|
|
10
10
|
/**
|
|
11
11
|
* Table page
|
|
12
12
|
* @param props Props
|
|
@@ -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))
|
|
@@ -60,7 +61,7 @@ export function TablePage(props) {
|
|
|
60
61
|
}
|
|
61
62
|
}, [rect]);
|
|
62
63
|
// Layout
|
|
63
|
-
return (React.createElement(CommonPage, { ...pageProps, scrollContainer: CommonPageScrollContainer
|
|
64
|
+
return (React.createElement(CommonPage, { ...pageProps, scrollContainer: CommonPageScrollContainer },
|
|
64
65
|
React.createElement(Stack, null,
|
|
65
66
|
React.createElement(Box, { ref: dimensions[0][0], sx: {
|
|
66
67
|
paddingBottom: pageProps.paddings
|
|
@@ -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
|
@@ -106,7 +106,7 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
106
106
|
autoLoad = true,
|
|
107
107
|
defaultOrderBy,
|
|
108
108
|
defaultOrderByAsc,
|
|
109
|
-
height =
|
|
109
|
+
height = document.documentElement.clientHeight,
|
|
110
110
|
width = '100%',
|
|
111
111
|
mRef,
|
|
112
112
|
oRef,
|
|
@@ -248,6 +248,9 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
248
248
|
...add
|
|
249
249
|
};
|
|
250
250
|
Object.assign(state, resetState);
|
|
251
|
+
|
|
252
|
+
// Reset
|
|
253
|
+
setRows([]);
|
|
251
254
|
},
|
|
252
255
|
|
|
253
256
|
scrollTo(scrollOffset: number): void {
|
package/src/mu/DataGridEx.tsx
CHANGED
|
@@ -241,7 +241,7 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
241
241
|
sortLabel = headerCellRenderer({
|
|
242
242
|
cellProps,
|
|
243
243
|
column,
|
|
244
|
-
columnIndex: index,
|
|
244
|
+
columnIndex: checkable ? index - 1 : index, // Ignore the checkbox case,
|
|
245
245
|
states
|
|
246
246
|
});
|
|
247
247
|
} else if (sortable && field != null) {
|
|
@@ -306,7 +306,7 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
306
306
|
const cell = footerItemRenderer
|
|
307
307
|
? footerItemRenderer(rows, {
|
|
308
308
|
column,
|
|
309
|
-
index,
|
|
309
|
+
index: checkable ? index - 1 : index, // Ignore the checkbox case
|
|
310
310
|
states,
|
|
311
311
|
cellProps,
|
|
312
312
|
checkable
|
|
@@ -120,19 +120,19 @@ export namespace DataGridRenderers {
|
|
|
120
120
|
export function defaultFooterItemRenderer<T>(
|
|
121
121
|
_rows: T[],
|
|
122
122
|
{ index, states, checkable }: DataGridExFooterItemRendererProps<T>,
|
|
123
|
-
location: number =
|
|
123
|
+
location: number = 0
|
|
124
124
|
) {
|
|
125
125
|
const { selectedItems, loadedItems, hasNextPage } = states;
|
|
126
126
|
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
if (index === location) {
|
|
128
|
+
if (checkable) {
|
|
129
|
+
return [
|
|
130
|
+
selectedItems.length,
|
|
131
|
+
loadedItems.toLocaleString() + (hasNextPage ? '+' : '')
|
|
132
|
+
].join(' / ');
|
|
133
|
+
} else {
|
|
134
|
+
return loadedItems.toLocaleString() + (hasNextPage ? '+' : '');
|
|
135
|
+
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
return undefined;
|
|
@@ -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
|
*/
|
|
@@ -91,7 +96,7 @@ export interface ResponsibleContainerProps<
|
|
|
91
96
|
/**
|
|
92
97
|
* Listbox SX (dataGrid determines the case)
|
|
93
98
|
*/
|
|
94
|
-
listBoxSx?: (dataGrid: boolean) => SxProps<Theme>;
|
|
99
|
+
listBoxSx?: (dataGrid: boolean, height: number) => SxProps<Theme>;
|
|
95
100
|
|
|
96
101
|
/**
|
|
97
102
|
* Load data callback
|
|
@@ -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
|
*/
|
|
@@ -132,6 +142,16 @@ interface LocalRefs {
|
|
|
132
142
|
mounted?: boolean;
|
|
133
143
|
}
|
|
134
144
|
|
|
145
|
+
function getDefaultSearchBoxSx(paddings: {}): SxProps<Theme> {
|
|
146
|
+
const half = MUGlobal.half(paddings);
|
|
147
|
+
return {
|
|
148
|
+
paddingLeft: (theme) => theme.spacing(0.5),
|
|
149
|
+
paddingRight: (theme) => theme.spacing(0.5),
|
|
150
|
+
paddingTop: half,
|
|
151
|
+
marginBottom: half
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
135
155
|
/**
|
|
136
156
|
* Responsible container
|
|
137
157
|
* @param props Props
|
|
@@ -145,7 +165,9 @@ export function ResponsibleContainer<
|
|
|
145
165
|
const {
|
|
146
166
|
adjustHeight,
|
|
147
167
|
columns,
|
|
168
|
+
containerBoxSx,
|
|
148
169
|
dataGridMinWidth = DataGridExCalColumns(columns).total,
|
|
170
|
+
elementReady,
|
|
149
171
|
fields,
|
|
150
172
|
fieldTemplate,
|
|
151
173
|
height,
|
|
@@ -154,7 +176,7 @@ export function ResponsibleContainer<
|
|
|
154
176
|
mRef,
|
|
155
177
|
paddings = MUGlobal.pagePaddings,
|
|
156
178
|
pullToRefresh = true,
|
|
157
|
-
searchBoxSx =
|
|
179
|
+
searchBoxSx = getDefaultSearchBoxSx(paddings),
|
|
158
180
|
sizeReadyMiliseconds = 0,
|
|
159
181
|
...rest
|
|
160
182
|
} = props;
|
|
@@ -207,6 +229,7 @@ export function ResponsibleContainer<
|
|
|
207
229
|
const lastRect = state.rect;
|
|
208
230
|
|
|
209
231
|
// 32 = scroll bar width
|
|
232
|
+
console.log(lastRect, rect);
|
|
210
233
|
if (
|
|
211
234
|
lastRect != null &&
|
|
212
235
|
state.mounted !== true &&
|
|
@@ -228,7 +251,7 @@ export function ResponsibleContainer<
|
|
|
228
251
|
// Create list
|
|
229
252
|
const [list, showDataGrid] = (() => {
|
|
230
253
|
// No layout
|
|
231
|
-
if (rect == null) return [null,
|
|
254
|
+
if (rect == null) return [null, undefined];
|
|
232
255
|
|
|
233
256
|
// Width
|
|
234
257
|
const width = rect.width;
|
|
@@ -242,7 +265,9 @@ export function ResponsibleContainer<
|
|
|
242
265
|
heightLocal = height;
|
|
243
266
|
} else {
|
|
244
267
|
// Auto calculation
|
|
245
|
-
heightLocal =
|
|
268
|
+
heightLocal =
|
|
269
|
+
document.documentElement.clientHeight -
|
|
270
|
+
Math.round(rect.bottom + 1);
|
|
246
271
|
|
|
247
272
|
const style = window.getComputedStyle(dimensions[0][1]!);
|
|
248
273
|
const boxMargin = parseFloat(style.marginBottom);
|
|
@@ -258,13 +283,23 @@ export function ResponsibleContainer<
|
|
|
258
283
|
delete rest.itemRenderer;
|
|
259
284
|
|
|
260
285
|
return [
|
|
261
|
-
<Box
|
|
286
|
+
<Box
|
|
287
|
+
sx={
|
|
288
|
+
listBoxSx == null
|
|
289
|
+
? undefined
|
|
290
|
+
: listBoxSx(true, heightLocal)
|
|
291
|
+
}
|
|
292
|
+
>
|
|
262
293
|
<DataGridEx<T>
|
|
263
294
|
autoLoad={!hasFields}
|
|
264
295
|
height={heightLocal}
|
|
265
296
|
width={rect.width}
|
|
266
297
|
loadData={localLoadData}
|
|
267
298
|
mRef={mRefs}
|
|
299
|
+
outerRef={(element?: HTMLDivElement) => {
|
|
300
|
+
if (element != null && elementReady)
|
|
301
|
+
elementReady(element, true);
|
|
302
|
+
}}
|
|
268
303
|
columns={columns}
|
|
269
304
|
{...rest}
|
|
270
305
|
/>
|
|
@@ -284,13 +319,22 @@ export function ResponsibleContainer<
|
|
|
284
319
|
delete rest.selectable;
|
|
285
320
|
|
|
286
321
|
return [
|
|
287
|
-
<Box
|
|
322
|
+
<Box
|
|
323
|
+
sx={
|
|
324
|
+
listBoxSx == null
|
|
325
|
+
? undefined
|
|
326
|
+
: listBoxSx(false, heightLocal)
|
|
327
|
+
}
|
|
328
|
+
>
|
|
288
329
|
<ScrollerListEx<T>
|
|
289
330
|
autoLoad={!hasFields}
|
|
290
|
-
width={rect.width}
|
|
291
331
|
height={heightLocal}
|
|
292
332
|
loadData={localLoadData}
|
|
293
333
|
mRef={mRefs}
|
|
334
|
+
oRef={(element) => {
|
|
335
|
+
if (element != null && elementReady)
|
|
336
|
+
elementReady(element, false);
|
|
337
|
+
}}
|
|
294
338
|
{...rest}
|
|
295
339
|
/>
|
|
296
340
|
</Box>,
|
|
@@ -298,21 +342,37 @@ export function ResponsibleContainer<
|
|
|
298
342
|
];
|
|
299
343
|
})();
|
|
300
344
|
|
|
345
|
+
const searchBar = React.useMemo(() => {
|
|
346
|
+
if (!hasFields || showDataGrid == null) return;
|
|
347
|
+
return (
|
|
348
|
+
<SearchBar
|
|
349
|
+
fields={fields}
|
|
350
|
+
onSubmit={onSubmit}
|
|
351
|
+
className={`searchBar${showDataGrid ? 'Grid' : 'List'}`}
|
|
352
|
+
/>
|
|
353
|
+
);
|
|
354
|
+
}, [showDataGrid, hasFields]);
|
|
355
|
+
|
|
301
356
|
// Pull container
|
|
302
|
-
const pullContainer =
|
|
303
|
-
|
|
357
|
+
const pullContainer =
|
|
358
|
+
showDataGrid == null
|
|
359
|
+
? undefined
|
|
360
|
+
: showDataGrid
|
|
304
361
|
? '.DataGridEx-Body'
|
|
305
|
-
: '.ScrollerListEx-Body'
|
|
306
|
-
: undefined;
|
|
362
|
+
: '.ScrollerListEx-Body';
|
|
307
363
|
|
|
308
364
|
// Layout
|
|
309
365
|
return (
|
|
310
|
-
<
|
|
366
|
+
<Box
|
|
367
|
+
sx={
|
|
368
|
+
containerBoxSx == null || showDataGrid == null
|
|
369
|
+
? undefined
|
|
370
|
+
: containerBoxSx(showDataGrid)
|
|
371
|
+
}
|
|
372
|
+
>
|
|
311
373
|
<Stack>
|
|
312
374
|
<Box ref={dimensions[0][0]} sx={searchBoxSx}>
|
|
313
|
-
{
|
|
314
|
-
<SearchBar fields={fields} onSubmit={onSubmit} />
|
|
315
|
-
)}
|
|
375
|
+
{searchBar}
|
|
316
376
|
</Box>
|
|
317
377
|
{list}
|
|
318
378
|
</Stack>
|
|
@@ -330,6 +390,6 @@ export function ResponsibleContainer<
|
|
|
330
390
|
}}
|
|
331
391
|
/>
|
|
332
392
|
)}
|
|
333
|
-
</
|
|
393
|
+
</Box>
|
|
334
394
|
);
|
|
335
395
|
}
|
package/src/mu/SearchBar.tsx
CHANGED
|
@@ -99,18 +99,18 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
99
99
|
// Drawer open / close
|
|
100
100
|
const [open, updateOpen] = React.useState(false);
|
|
101
101
|
|
|
102
|
-
//
|
|
103
|
-
const
|
|
102
|
+
// State
|
|
103
|
+
const state = React.useRef<{
|
|
104
104
|
form?: HTMLFormElement;
|
|
105
105
|
moreForm?: HTMLFormElement;
|
|
106
106
|
submitSeed?: number;
|
|
107
107
|
lastMaxWidth?: number;
|
|
108
|
-
}>({});
|
|
108
|
+
}>({}).current;
|
|
109
109
|
|
|
110
110
|
// Watch container
|
|
111
111
|
const { dimensions } = useDimensions(1, (target, rect) => {
|
|
112
112
|
// Same logic from resetButtonRef
|
|
113
|
-
if (rect.width ===
|
|
113
|
+
if (rect.width === state.lastMaxWidth) return false;
|
|
114
114
|
|
|
115
115
|
// Len
|
|
116
116
|
const len = target.children.length;
|
|
@@ -143,10 +143,10 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
143
143
|
|
|
144
144
|
// Container width
|
|
145
145
|
let maxWidth = containerRect.width;
|
|
146
|
-
if (maxWidth ===
|
|
146
|
+
if (maxWidth === state.lastMaxWidth) {
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
state.lastMaxWidth = maxWidth;
|
|
150
150
|
|
|
151
151
|
// More button
|
|
152
152
|
const buttonMore = resetButton.previousElementSibling!;
|
|
@@ -241,7 +241,7 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
241
241
|
const handleForm = (event: React.FormEvent<HTMLFormElement>) => {
|
|
242
242
|
if (event.nativeEvent.cancelable && !event.nativeEvent.composed) return;
|
|
243
243
|
|
|
244
|
-
if (
|
|
244
|
+
if (state.form == null) state.form = event.currentTarget;
|
|
245
245
|
|
|
246
246
|
handleSubmit();
|
|
247
247
|
};
|
|
@@ -255,7 +255,7 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
255
255
|
const moreFormChange = (event: React.FormEvent<HTMLFormElement>) => {
|
|
256
256
|
if (event.nativeEvent.cancelable && !event.nativeEvent.composed) return;
|
|
257
257
|
|
|
258
|
-
if (
|
|
258
|
+
if (state.moreForm == null) state.moreForm = event.currentTarget;
|
|
259
259
|
|
|
260
260
|
handleSubmit();
|
|
261
261
|
};
|
|
@@ -263,8 +263,8 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
263
263
|
// Reset
|
|
264
264
|
const handleReset = () => {
|
|
265
265
|
// Clear form values
|
|
266
|
-
if (
|
|
267
|
-
if (
|
|
266
|
+
if (state.form != null) resetForm(state.form);
|
|
267
|
+
if (state.moreForm != null) resetForm(state.moreForm);
|
|
268
268
|
|
|
269
269
|
// Resubmit
|
|
270
270
|
handleSubmitInstant(true);
|
|
@@ -272,23 +272,23 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
272
272
|
|
|
273
273
|
// Submit
|
|
274
274
|
const handleSubmit = (delay = 480) => {
|
|
275
|
-
if (
|
|
276
|
-
clearTimeout(
|
|
275
|
+
if (state.submitSeed != null) {
|
|
276
|
+
clearTimeout(state.submitSeed);
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
// Delay the change
|
|
280
|
-
|
|
280
|
+
state.submitSeed = window.setTimeout(handleSubmitInstant, delay);
|
|
281
281
|
};
|
|
282
282
|
|
|
283
283
|
// Submit at once
|
|
284
284
|
const handleSubmitInstant = (reset: boolean = false) => {
|
|
285
285
|
// Reset timeout
|
|
286
|
-
|
|
286
|
+
state.submitSeed = undefined;
|
|
287
287
|
|
|
288
288
|
// Prepare data
|
|
289
|
-
const data = new FormData(
|
|
290
|
-
if (
|
|
291
|
-
DomUtils.mergeFormData(data, new FormData(
|
|
289
|
+
const data = new FormData(state.form);
|
|
290
|
+
if (state.moreForm != null) {
|
|
291
|
+
DomUtils.mergeFormData(data, new FormData(state.moreForm));
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
onSubmit(data, reset);
|
|
@@ -296,15 +296,17 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
296
296
|
|
|
297
297
|
// First loading
|
|
298
298
|
React.useEffect(() => {
|
|
299
|
-
// Delayed way
|
|
300
|
-
handleSubmit(100);
|
|
301
|
-
|
|
302
299
|
return () => {
|
|
303
300
|
// Clear the seeds
|
|
304
|
-
if (
|
|
301
|
+
if (state.submitSeed != null) clearTimeout(state.submitSeed);
|
|
305
302
|
};
|
|
306
303
|
}, []);
|
|
307
304
|
|
|
305
|
+
React.useEffect(() => {
|
|
306
|
+
// Delayed way
|
|
307
|
+
handleSubmit(100);
|
|
308
|
+
}, [className]);
|
|
309
|
+
|
|
308
310
|
// Layout
|
|
309
311
|
return (
|
|
310
312
|
<React.Fragment>
|
|
@@ -313,7 +315,7 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
313
315
|
className={className}
|
|
314
316
|
onChange={handleForm}
|
|
315
317
|
ref={(form) => {
|
|
316
|
-
if (form)
|
|
318
|
+
if (form) state.form = form;
|
|
317
319
|
}}
|
|
318
320
|
>
|
|
319
321
|
<Stack
|
|
@@ -374,7 +376,7 @@ export function SearchBar(props: SearchBarProps) {
|
|
|
374
376
|
<form
|
|
375
377
|
onChange={moreFormChange}
|
|
376
378
|
ref={(form) => {
|
|
377
|
-
if (form)
|
|
379
|
+
if (form) state.moreForm = form;
|
|
378
380
|
}}
|
|
379
381
|
>
|
|
380
382
|
<Stack
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { FabBox } from '../FabBox';
|
|
3
3
|
import { ScrollTopFab } from '../ScrollTopFab';
|
|
4
|
-
import { PullToRefreshUI } from '../PullToRefreshUI';
|
|
5
4
|
import { Labels } from '../../app/Labels';
|
|
6
5
|
import { MUGlobal } from '../MUGlobal';
|
|
7
6
|
import { CommonPageProps } from './CommonPageProps';
|
|
@@ -10,11 +9,6 @@ import { ReactAppStateDetector } from '../../app/ReactApp';
|
|
|
10
9
|
import { Container, Fab } from '@mui/material';
|
|
11
10
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
|
12
11
|
|
|
13
|
-
/**
|
|
14
|
-
* Default pull container
|
|
15
|
-
*/
|
|
16
|
-
export const CommonPagePullContainer = '#page-container';
|
|
17
|
-
|
|
18
12
|
/**
|
|
19
13
|
* Default scroll container
|
|
20
14
|
*/
|
|
@@ -41,7 +35,6 @@ export function CommonPage(props: CommonPageProps) {
|
|
|
41
35
|
paddings = MUGlobal.pagePaddings,
|
|
42
36
|
scrollContainer,
|
|
43
37
|
targetFields,
|
|
44
|
-
pullContainer,
|
|
45
38
|
sx = {},
|
|
46
39
|
...rest
|
|
47
40
|
} = props;
|
|
@@ -125,20 +118,6 @@ export function CommonPage(props: CommonPageProps) {
|
|
|
125
118
|
</FabBox>
|
|
126
119
|
{children}
|
|
127
120
|
</Container>
|
|
128
|
-
{onRefresh != null && pullContainer != null && (
|
|
129
|
-
<PullToRefreshUI
|
|
130
|
-
mainElement={pullContainer}
|
|
131
|
-
triggerElement={pullContainer}
|
|
132
|
-
instructionsPullToRefresh={labels.pullToRefresh}
|
|
133
|
-
instructionsReleaseToRefresh={labels.releaseToRefresh}
|
|
134
|
-
instructionsRefreshing={labels.refreshing}
|
|
135
|
-
onRefresh={onRefresh}
|
|
136
|
-
shouldPullToRefresh={() => {
|
|
137
|
-
const container = document.querySelector(pullContainer);
|
|
138
|
-
return !container?.scrollTop;
|
|
139
|
-
}}
|
|
140
|
-
/>
|
|
141
|
-
)}
|
|
142
121
|
</React.Fragment>
|
|
143
122
|
);
|
|
144
123
|
}
|
|
@@ -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);
|
|
@@ -113,18 +114,9 @@ export function DataGridPage<
|
|
|
113
114
|
ref.reset({ data });
|
|
114
115
|
}, [ref, data]);
|
|
115
116
|
|
|
116
|
-
// Pull container id
|
|
117
|
-
const pullContainer = states.element?.parentElement
|
|
118
|
-
? '.DataGridEx-Body'
|
|
119
|
-
: undefined;
|
|
120
|
-
|
|
121
117
|
// Layout
|
|
122
118
|
return (
|
|
123
|
-
<CommonPage
|
|
124
|
-
{...pageProps}
|
|
125
|
-
scrollContainer={states.element}
|
|
126
|
-
pullContainer={pullContainer}
|
|
127
|
-
>
|
|
119
|
+
<CommonPage {...pageProps} scrollContainer={states.element}>
|
|
128
120
|
<Stack>
|
|
129
121
|
<Box
|
|
130
122
|
ref={dimensions[0][0]}
|
|
@@ -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);
|
|
@@ -113,11 +114,6 @@ export function FixedListPage<
|
|
|
113
114
|
}
|
|
114
115
|
}, [rect]);
|
|
115
116
|
|
|
116
|
-
// Pull container id
|
|
117
|
-
const pullContainer = scrollContainer?.parentElement
|
|
118
|
-
? '#' + scrollContainer?.parentElement.id
|
|
119
|
-
: undefined;
|
|
120
|
-
|
|
121
117
|
const { paddings, ...pageRest } = pageProps;
|
|
122
118
|
|
|
123
119
|
// Layout
|
|
@@ -126,7 +122,6 @@ export function FixedListPage<
|
|
|
126
122
|
{...pageRest}
|
|
127
123
|
paddings={{}}
|
|
128
124
|
scrollContainer={scrollContainer}
|
|
129
|
-
pullContainer={pullContainer}
|
|
130
125
|
>
|
|
131
126
|
<Stack>
|
|
132
127
|
<Box ref={dimensions[0][0]} sx={{ padding: paddings }}>
|
|
@@ -7,11 +7,7 @@ import useCombinedRefs from '../../uses/useCombinedRefs';
|
|
|
7
7
|
import { MUGlobal } from '../MUGlobal';
|
|
8
8
|
import { ScrollerListEx } from '../ScrollerListEx';
|
|
9
9
|
import { SearchBar } from '../SearchBar';
|
|
10
|
-
import {
|
|
11
|
-
CommonPage,
|
|
12
|
-
CommonPagePullContainer,
|
|
13
|
-
CommonPageScrollContainer
|
|
14
|
-
} from './CommonPage';
|
|
10
|
+
import { CommonPage, CommonPageScrollContainer } from './CommonPage';
|
|
15
11
|
import { ListPageProps } from './ListPageProps';
|
|
16
12
|
|
|
17
13
|
/**
|
|
@@ -69,11 +65,7 @@ export function ListPage<
|
|
|
69
65
|
|
|
70
66
|
// Layout
|
|
71
67
|
return (
|
|
72
|
-
<CommonPage
|
|
73
|
-
{...pageProps}
|
|
74
|
-
scrollContainer={CommonPageScrollContainer}
|
|
75
|
-
pullContainer={CommonPagePullContainer}
|
|
76
|
-
>
|
|
68
|
+
<CommonPage {...pageProps} scrollContainer={CommonPageScrollContainer}>
|
|
77
69
|
<Stack>
|
|
78
70
|
<Box
|
|
79
71
|
sx={{
|