@etsoo/react 1.4.13 → 1.4.17
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 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/mu/MobileListItemRenderer.d.ts +7 -0
- package/lib/mu/MobileListItemRenderer.js +7 -0
- package/lib/mu/ResponsibleContainer.d.ts +69 -0
- package/lib/mu/ResponsibleContainer.js +82 -0
- package/lib/mu/TabBox.d.ts +1 -1
- package/lib/mu/TabBox.js +2 -1
- package/package.json +3 -3
- package/src/components/ScrollerList.tsx +3 -6
- package/src/index.ts +1 -0
- package/src/mu/MobileListItemRenderer.tsx +7 -0
- package/src/mu/ResponsibleContainer.tsx +245 -0
- package/src/mu/TabBox.tsx +3 -2
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { Utils } from '@etsoo/shared';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { FixedSizeList, VariableSizeList } from 'react-window';
|
|
3
4
|
import useCombinedRefs from '../uses/useCombinedRefs';
|
|
4
5
|
import { GridSizeGet } from './GridLoader';
|
|
5
6
|
// Calculate loadBatchSize
|
|
6
7
|
const calculateBatchSize = (height, itemSize) => {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
const size = Utils.getResult(itemSize, 0);
|
|
9
|
+
return 2 + Math.ceil(height / size);
|
|
9
10
|
};
|
|
10
11
|
/**
|
|
11
12
|
* Scroller vertical list
|
package/lib/index.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ export * from './mu/OptionGroup';
|
|
|
56
56
|
export * from './mu/PList';
|
|
57
57
|
export * from './mu/ProgressCount';
|
|
58
58
|
export * from './mu/PullToRefreshUI';
|
|
59
|
+
export * from './mu/ResponsibleContainer';
|
|
59
60
|
export * from './mu/RLink';
|
|
60
61
|
export * from './mu/ScrollerListEx';
|
|
61
62
|
export * from './mu/ScrollTopFab';
|
package/lib/index.js
CHANGED
|
@@ -59,6 +59,7 @@ export * from './mu/OptionGroup';
|
|
|
59
59
|
export * from './mu/PList';
|
|
60
60
|
export * from './mu/ProgressCount';
|
|
61
61
|
export * from './mu/PullToRefreshUI';
|
|
62
|
+
export * from './mu/ResponsibleContainer';
|
|
62
63
|
export * from './mu/RLink';
|
|
63
64
|
export * from './mu/ScrollerListEx';
|
|
64
65
|
export * from './mu/ScrollTopFab';
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ListItemReact } from '../components/ListItemReact';
|
|
3
3
|
import { ScrollerListExInnerItemRendererProps } from './ScrollerListEx';
|
|
4
|
+
/**
|
|
5
|
+
* Default mobile list item renderer
|
|
6
|
+
* @param param0 List renderer props
|
|
7
|
+
* @param margin Margin
|
|
8
|
+
* @param renderer Renderer for card content
|
|
9
|
+
* @returns Component
|
|
10
|
+
*/
|
|
4
11
|
export declare function MobileListItemRenderer<T>({ data, itemHeight }: ScrollerListExInnerItemRendererProps<T>, margin: {}, renderer: (data: T) => [
|
|
5
12
|
string,
|
|
6
13
|
string | undefined,
|
|
@@ -12,6 +12,13 @@ function getActions(input) {
|
|
|
12
12
|
});
|
|
13
13
|
return actions;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Default mobile list item renderer
|
|
17
|
+
* @param param0 List renderer props
|
|
18
|
+
* @param margin Margin
|
|
19
|
+
* @param renderer Renderer for card content
|
|
20
|
+
* @returns Component
|
|
21
|
+
*/
|
|
15
22
|
export function MobileListItemRenderer({ data, itemHeight }, margin, renderer) {
|
|
16
23
|
// Loading
|
|
17
24
|
if (data == null)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { DataTypes } from '@etsoo/shared';
|
|
2
|
+
import { SxProps, Theme } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { ListChildComponentProps } from 'react-window';
|
|
5
|
+
import { GridColumn } from '../components/GridColumn';
|
|
6
|
+
import { GridJsonData } from '../components/GridLoader';
|
|
7
|
+
import { DataGridExProps } from './DataGridEx';
|
|
8
|
+
import { GridMethodRef } from './GridMethodRef';
|
|
9
|
+
import { ScrollerListExInnerItemRendererProps } from './ScrollerListEx';
|
|
10
|
+
export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate> extends Omit<DataGridExProps<T>, 'height' | 'itemKey' | 'loadData' | 'mRef' | 'onScroll' | 'onItemsRendered'> {
|
|
11
|
+
/**
|
|
12
|
+
* Height will be deducted
|
|
13
|
+
* @param height Current calcuated height
|
|
14
|
+
*/
|
|
15
|
+
adjustHeight?: (height: number) => number;
|
|
16
|
+
/**
|
|
17
|
+
* Columns
|
|
18
|
+
*/
|
|
19
|
+
columns: GridColumn<T>[];
|
|
20
|
+
/**
|
|
21
|
+
* Min width to show Datagrid
|
|
22
|
+
*/
|
|
23
|
+
dataGridMinWidth?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Search fields
|
|
26
|
+
*/
|
|
27
|
+
fields?: React.ReactElement[];
|
|
28
|
+
/**
|
|
29
|
+
* Search field template
|
|
30
|
+
*/
|
|
31
|
+
fieldTemplate?: F;
|
|
32
|
+
/**
|
|
33
|
+
* Grid height
|
|
34
|
+
*/
|
|
35
|
+
height?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Inner item renderer
|
|
38
|
+
*/
|
|
39
|
+
innerItemRenderer: (props: ScrollerListExInnerItemRendererProps<T>) => React.ReactNode;
|
|
40
|
+
/**
|
|
41
|
+
* Item renderer
|
|
42
|
+
*/
|
|
43
|
+
itemRenderer?: (props: ListChildComponentProps<T>) => React.ReactElement;
|
|
44
|
+
/**
|
|
45
|
+
* Item size, a function indicates its a variable size list
|
|
46
|
+
*/
|
|
47
|
+
itemSize: ((index: number) => number) | number;
|
|
48
|
+
/**
|
|
49
|
+
* Listbox SX (dataGrid determines the case)
|
|
50
|
+
*/
|
|
51
|
+
listBoxSx?: (dataGrid: boolean) => SxProps<Theme>;
|
|
52
|
+
/**
|
|
53
|
+
* Load data callback
|
|
54
|
+
*/
|
|
55
|
+
loadData: (data: GridJsonData & DataTypes.BasicTemplateType<F>) => PromiseLike<T[] | null | undefined>;
|
|
56
|
+
/**
|
|
57
|
+
* Methods
|
|
58
|
+
*/
|
|
59
|
+
mRef?: React.MutableRefObject<GridMethodRef | undefined>;
|
|
60
|
+
/**
|
|
61
|
+
* Searchbox SX
|
|
62
|
+
*/
|
|
63
|
+
searchBoxSx?: SxProps<Theme>;
|
|
64
|
+
/**
|
|
65
|
+
* Size ready to read miliseconds span
|
|
66
|
+
*/
|
|
67
|
+
sizeReadyMiliseconds?: number;
|
|
68
|
+
}
|
|
69
|
+
export declare function ResponsibleContainer<T extends {}, F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate>(props: ResponsibleContainerProps<T, F>): JSX.Element;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Box, Stack } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { GridDataGet } from '../components/GridLoader';
|
|
4
|
+
import useCombinedRefs from '../uses/useCombinedRefs';
|
|
5
|
+
import { useDimensions } from '../uses/useDimensions';
|
|
6
|
+
import { DataGridEx, DataGridExCalColumns } from './DataGridEx';
|
|
7
|
+
import { ScrollerListEx } from './ScrollerListEx';
|
|
8
|
+
import { SearchBar } from './SearchBar';
|
|
9
|
+
export function ResponsibleContainer(props) {
|
|
10
|
+
var _a;
|
|
11
|
+
// Destruct
|
|
12
|
+
const { adjustHeight, columns, dataGridMinWidth = DataGridExCalColumns(columns).total, fields, fieldTemplate, height, listBoxSx, loadData, mRef, searchBoxSx, sizeReadyMiliseconds = 0, ...rest } = props;
|
|
13
|
+
// Refs
|
|
14
|
+
const refs = React.useRef({});
|
|
15
|
+
const mRefs = useCombinedRefs(mRef, (ref) => {
|
|
16
|
+
if (ref == null)
|
|
17
|
+
return;
|
|
18
|
+
refs.current.ref = ref;
|
|
19
|
+
});
|
|
20
|
+
// Has fields
|
|
21
|
+
const hasFields = fields != null && fields.length > 0;
|
|
22
|
+
// Watch container
|
|
23
|
+
const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
|
|
24
|
+
const rect = dimensions[0][2];
|
|
25
|
+
const showDataGrid = ((_a = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _a !== void 0 ? _a : 0) >= dataGridMinWidth;
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
if (rect != null && rect.height > 50 && height == null) {
|
|
28
|
+
let gridHeight = window.innerHeight - Math.round(rect.top + rect.height + 1);
|
|
29
|
+
const style = window.getComputedStyle(dimensions[0][1]);
|
|
30
|
+
const boxPadding = parseFloat(style.paddingLeft);
|
|
31
|
+
if (!isNaN(boxPadding))
|
|
32
|
+
gridHeight -= 2 * boxPadding;
|
|
33
|
+
if (adjustHeight != null) {
|
|
34
|
+
gridHeight -= adjustHeight(gridHeight);
|
|
35
|
+
}
|
|
36
|
+
if (gridHeight !== refs.current.height) {
|
|
37
|
+
refs.current.height = gridHeight;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, [rect]);
|
|
41
|
+
const localLoadData = (props) => {
|
|
42
|
+
const data = GridDataGet(props, fieldTemplate);
|
|
43
|
+
return loadData(data);
|
|
44
|
+
};
|
|
45
|
+
const gridHeight = refs.current.height;
|
|
46
|
+
const list = React.useMemo(() => {
|
|
47
|
+
if (gridHeight == null)
|
|
48
|
+
return;
|
|
49
|
+
if (showDataGrid) {
|
|
50
|
+
// Delete
|
|
51
|
+
delete rest.itemRenderer;
|
|
52
|
+
return (React.createElement(Box, { sx: listBoxSx == null ? undefined : listBoxSx(true) },
|
|
53
|
+
React.createElement(DataGridEx, { autoLoad: !hasFields, height: gridHeight, loadData: localLoadData, mRef: mRefs, columns: columns, ...rest })));
|
|
54
|
+
}
|
|
55
|
+
// Delete
|
|
56
|
+
delete rest.checkable;
|
|
57
|
+
delete rest.borderRowsCount;
|
|
58
|
+
delete rest.bottomHeight;
|
|
59
|
+
delete rest.footerItemRenderer;
|
|
60
|
+
delete rest.headerHeight;
|
|
61
|
+
delete rest.hideFooter;
|
|
62
|
+
delete rest.hoverColor;
|
|
63
|
+
delete rest.selectable;
|
|
64
|
+
return (React.createElement(Box, { sx: listBoxSx == null ? undefined : listBoxSx(false) },
|
|
65
|
+
React.createElement(ScrollerListEx, { autoLoad: !hasFields, height: gridHeight, loadData: localLoadData, mRef: mRefs, ...rest })));
|
|
66
|
+
}, [gridHeight, showDataGrid]);
|
|
67
|
+
// On submit callback
|
|
68
|
+
const onSubmit = (data, _reset) => {
|
|
69
|
+
console.log(data, rect, refs.current.ref, showDataGrid);
|
|
70
|
+
if (data == null || rect == null || refs.current.ref == null)
|
|
71
|
+
return;
|
|
72
|
+
refs.current.ref.reset({ data });
|
|
73
|
+
};
|
|
74
|
+
React.useEffect(() => {
|
|
75
|
+
console.log('useEffect', rect, refs.current.ref, showDataGrid);
|
|
76
|
+
}, []);
|
|
77
|
+
// Layout
|
|
78
|
+
return (React.createElement(Stack, null,
|
|
79
|
+
hasFields && (React.createElement(Box, { ref: dimensions[0][0], sx: searchBoxSx },
|
|
80
|
+
React.createElement(SearchBar, { fields: fields, onSubmit: onSubmit }))),
|
|
81
|
+
list));
|
|
82
|
+
}
|
package/lib/mu/TabBox.d.ts
CHANGED
package/lib/mu/TabBox.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Utils } from '@etsoo/shared';
|
|
1
2
|
import { Box, Tab, Tabs } from '@mui/material';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
/**
|
|
@@ -20,5 +21,5 @@ export function TabBox(props) {
|
|
|
20
21
|
if (onChange)
|
|
21
22
|
onChange(event, newValue);
|
|
22
23
|
}, ...rest }, tabs.map(({ children, panel, ...tabRest }, index) => (React.createElement(Tab, { key: index, value: index, ...tabRest }))))),
|
|
23
|
-
tabs.map(({ children, panel }, index) => (React.createElement(Box, { key: index, hidden: value !== index, ...panel }, children)))));
|
|
24
|
+
tabs.map(({ children, panel }, index) => (React.createElement(Box, { key: index, hidden: value !== index, ...panel }, Utils.getResult(children, value === index))))));
|
|
24
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/react",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.17",
|
|
4
4
|
"description": "TypeScript ReactJs framework",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"@emotion/react": "^11.7.1",
|
|
51
51
|
"@emotion/style": "^0.8.0",
|
|
52
52
|
"@emotion/styled": "^11.6.0",
|
|
53
|
-
"@etsoo/appscript": "^1.2.
|
|
53
|
+
"@etsoo/appscript": "^1.2.21",
|
|
54
54
|
"@etsoo/notificationbase": "^1.1.0",
|
|
55
|
-
"@etsoo/shared": "^1.1.
|
|
55
|
+
"@etsoo/shared": "^1.1.3",
|
|
56
56
|
"@mui/icons-material": "^5.2.5",
|
|
57
57
|
"@mui/material": "^5.2.7",
|
|
58
58
|
"@reach/router": "^1.3.4",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Utils } from '@etsoo/shared';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import {
|
|
3
4
|
Align,
|
|
@@ -88,12 +89,8 @@ const calculateBatchSize = (
|
|
|
88
89
|
height: number,
|
|
89
90
|
itemSize: ((index: number) => number) | number
|
|
90
91
|
) => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Math.ceil(
|
|
94
|
-
height / (typeof itemSize === 'function' ? itemSize(0) : itemSize)
|
|
95
|
-
)
|
|
96
|
-
);
|
|
92
|
+
const size = Utils.getResult(itemSize, 0);
|
|
93
|
+
return 2 + Math.ceil(height / size);
|
|
97
94
|
};
|
|
98
95
|
|
|
99
96
|
/**
|
package/src/index.ts
CHANGED
|
@@ -63,6 +63,7 @@ export * from './mu/OptionGroup';
|
|
|
63
63
|
export * from './mu/PList';
|
|
64
64
|
export * from './mu/ProgressCount';
|
|
65
65
|
export * from './mu/PullToRefreshUI';
|
|
66
|
+
export * from './mu/ResponsibleContainer';
|
|
66
67
|
export * from './mu/RLink';
|
|
67
68
|
export * from './mu/ScrollerListEx';
|
|
68
69
|
export * from './mu/ScrollTopFab';
|
|
@@ -15,6 +15,13 @@ function getActions(input: (ListItemReact | boolean)[]): ListItemReact[] {
|
|
|
15
15
|
return actions;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Default mobile list item renderer
|
|
20
|
+
* @param param0 List renderer props
|
|
21
|
+
* @param margin Margin
|
|
22
|
+
* @param renderer Renderer for card content
|
|
23
|
+
* @returns Component
|
|
24
|
+
*/
|
|
18
25
|
export function MobileListItemRenderer<T>(
|
|
19
26
|
{ data, itemHeight }: ScrollerListExInnerItemRendererProps<T>,
|
|
20
27
|
margin: {},
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { DataTypes } from '@etsoo/shared';
|
|
2
|
+
import { Box, Stack, SxProps, Theme } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { ListChildComponentProps } from 'react-window';
|
|
5
|
+
import { GridColumn } from '../components/GridColumn';
|
|
6
|
+
import {
|
|
7
|
+
GridDataGet,
|
|
8
|
+
GridJsonData,
|
|
9
|
+
GridLoadDataProps
|
|
10
|
+
} from '../components/GridLoader';
|
|
11
|
+
import useCombinedRefs from '../uses/useCombinedRefs';
|
|
12
|
+
import { useDimensions } from '../uses/useDimensions';
|
|
13
|
+
import {
|
|
14
|
+
DataGridEx,
|
|
15
|
+
DataGridExCalColumns,
|
|
16
|
+
DataGridExProps
|
|
17
|
+
} from './DataGridEx';
|
|
18
|
+
import { GridMethodRef } from './GridMethodRef';
|
|
19
|
+
import {
|
|
20
|
+
ScrollerListEx,
|
|
21
|
+
ScrollerListExInnerItemRendererProps
|
|
22
|
+
} from './ScrollerListEx';
|
|
23
|
+
import { SearchBar } from './SearchBar';
|
|
24
|
+
|
|
25
|
+
export interface ResponsibleContainerProps<
|
|
26
|
+
T extends {},
|
|
27
|
+
F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
|
|
28
|
+
> extends Omit<
|
|
29
|
+
DataGridExProps<T>,
|
|
30
|
+
| 'height'
|
|
31
|
+
| 'itemKey'
|
|
32
|
+
| 'loadData'
|
|
33
|
+
| 'mRef'
|
|
34
|
+
| 'onScroll'
|
|
35
|
+
| 'onItemsRendered'
|
|
36
|
+
> {
|
|
37
|
+
/**
|
|
38
|
+
* Height will be deducted
|
|
39
|
+
* @param height Current calcuated height
|
|
40
|
+
*/
|
|
41
|
+
adjustHeight?: (height: number) => number;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Columns
|
|
45
|
+
*/
|
|
46
|
+
columns: GridColumn<T>[];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Min width to show Datagrid
|
|
50
|
+
*/
|
|
51
|
+
dataGridMinWidth?: number;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Search fields
|
|
55
|
+
*/
|
|
56
|
+
fields?: React.ReactElement[];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Search field template
|
|
60
|
+
*/
|
|
61
|
+
fieldTemplate?: F;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Grid height
|
|
65
|
+
*/
|
|
66
|
+
height?: number;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Inner item renderer
|
|
70
|
+
*/
|
|
71
|
+
innerItemRenderer: (
|
|
72
|
+
props: ScrollerListExInnerItemRendererProps<T>
|
|
73
|
+
) => React.ReactNode;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Item renderer
|
|
77
|
+
*/
|
|
78
|
+
itemRenderer?: (props: ListChildComponentProps<T>) => React.ReactElement;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Item size, a function indicates its a variable size list
|
|
82
|
+
*/
|
|
83
|
+
itemSize: ((index: number) => number) | number;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Listbox SX (dataGrid determines the case)
|
|
87
|
+
*/
|
|
88
|
+
listBoxSx?: (dataGrid: boolean) => SxProps<Theme>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Load data callback
|
|
92
|
+
*/
|
|
93
|
+
loadData: (
|
|
94
|
+
data: GridJsonData & DataTypes.BasicTemplateType<F>
|
|
95
|
+
) => PromiseLike<T[] | null | undefined>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Methods
|
|
99
|
+
*/
|
|
100
|
+
mRef?: React.MutableRefObject<GridMethodRef | undefined>;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Searchbox SX
|
|
104
|
+
*/
|
|
105
|
+
searchBoxSx?: SxProps<Theme>;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Size ready to read miliseconds span
|
|
109
|
+
*/
|
|
110
|
+
sizeReadyMiliseconds?: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface LocalRefs {
|
|
114
|
+
height?: number;
|
|
115
|
+
ref?: GridMethodRef;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function ResponsibleContainer<
|
|
119
|
+
T extends {},
|
|
120
|
+
F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
|
|
121
|
+
>(props: ResponsibleContainerProps<T, F>) {
|
|
122
|
+
// Destruct
|
|
123
|
+
const {
|
|
124
|
+
adjustHeight,
|
|
125
|
+
columns,
|
|
126
|
+
dataGridMinWidth = DataGridExCalColumns(columns).total,
|
|
127
|
+
fields,
|
|
128
|
+
fieldTemplate,
|
|
129
|
+
height,
|
|
130
|
+
listBoxSx,
|
|
131
|
+
loadData,
|
|
132
|
+
mRef,
|
|
133
|
+
searchBoxSx,
|
|
134
|
+
sizeReadyMiliseconds = 0,
|
|
135
|
+
...rest
|
|
136
|
+
} = props;
|
|
137
|
+
|
|
138
|
+
// Refs
|
|
139
|
+
const refs = React.useRef<LocalRefs>({});
|
|
140
|
+
|
|
141
|
+
const mRefs = useCombinedRefs(mRef, (ref: GridMethodRef) => {
|
|
142
|
+
if (ref == null) return;
|
|
143
|
+
refs.current.ref = ref;
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Has fields
|
|
147
|
+
const hasFields = fields != null && fields.length > 0;
|
|
148
|
+
|
|
149
|
+
// Watch container
|
|
150
|
+
const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
|
|
151
|
+
const rect = dimensions[0][2];
|
|
152
|
+
const showDataGrid = (rect?.width ?? 0) >= dataGridMinWidth;
|
|
153
|
+
|
|
154
|
+
React.useEffect(() => {
|
|
155
|
+
if (rect != null && rect.height > 50 && height == null) {
|
|
156
|
+
let gridHeight =
|
|
157
|
+
window.innerHeight - Math.round(rect.top + rect.height + 1);
|
|
158
|
+
|
|
159
|
+
const style = window.getComputedStyle(dimensions[0][1]!);
|
|
160
|
+
const boxPadding = parseFloat(style.paddingLeft);
|
|
161
|
+
if (!isNaN(boxPadding)) gridHeight -= 2 * boxPadding;
|
|
162
|
+
|
|
163
|
+
if (adjustHeight != null) {
|
|
164
|
+
gridHeight -= adjustHeight(gridHeight);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (gridHeight !== refs.current.height) {
|
|
168
|
+
refs.current.height = gridHeight;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, [rect]);
|
|
172
|
+
|
|
173
|
+
const localLoadData = (props: GridLoadDataProps) => {
|
|
174
|
+
const data = GridDataGet(props, fieldTemplate);
|
|
175
|
+
return loadData(data);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const gridHeight = refs.current.height;
|
|
179
|
+
const list = React.useMemo(() => {
|
|
180
|
+
if (gridHeight == null) return;
|
|
181
|
+
|
|
182
|
+
if (showDataGrid) {
|
|
183
|
+
// Delete
|
|
184
|
+
delete rest.itemRenderer;
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<Box sx={listBoxSx == null ? undefined : listBoxSx(true)}>
|
|
188
|
+
<DataGridEx<T>
|
|
189
|
+
autoLoad={!hasFields}
|
|
190
|
+
height={gridHeight}
|
|
191
|
+
loadData={localLoadData}
|
|
192
|
+
mRef={mRefs}
|
|
193
|
+
columns={columns}
|
|
194
|
+
{...rest}
|
|
195
|
+
/>
|
|
196
|
+
</Box>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Delete
|
|
201
|
+
delete rest.checkable;
|
|
202
|
+
delete rest.borderRowsCount;
|
|
203
|
+
delete rest.bottomHeight;
|
|
204
|
+
delete rest.footerItemRenderer;
|
|
205
|
+
delete rest.headerHeight;
|
|
206
|
+
delete rest.hideFooter;
|
|
207
|
+
delete rest.hoverColor;
|
|
208
|
+
delete rest.selectable;
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<Box sx={listBoxSx == null ? undefined : listBoxSx(false)}>
|
|
212
|
+
<ScrollerListEx<T>
|
|
213
|
+
autoLoad={!hasFields}
|
|
214
|
+
height={gridHeight}
|
|
215
|
+
loadData={localLoadData}
|
|
216
|
+
mRef={mRefs}
|
|
217
|
+
{...rest}
|
|
218
|
+
/>
|
|
219
|
+
</Box>
|
|
220
|
+
);
|
|
221
|
+
}, [gridHeight, showDataGrid]);
|
|
222
|
+
|
|
223
|
+
// On submit callback
|
|
224
|
+
const onSubmit = (data: FormData, _reset: boolean) => {
|
|
225
|
+
console.log(data, rect, refs.current.ref, showDataGrid);
|
|
226
|
+
if (data == null || rect == null || refs.current.ref == null) return;
|
|
227
|
+
refs.current.ref.reset({ data });
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
React.useEffect(() => {
|
|
231
|
+
console.log('useEffect', rect, refs.current.ref, showDataGrid);
|
|
232
|
+
}, []);
|
|
233
|
+
|
|
234
|
+
// Layout
|
|
235
|
+
return (
|
|
236
|
+
<Stack>
|
|
237
|
+
{hasFields && (
|
|
238
|
+
<Box ref={dimensions[0][0]} sx={searchBoxSx}>
|
|
239
|
+
<SearchBar fields={fields} onSubmit={onSubmit} />
|
|
240
|
+
</Box>
|
|
241
|
+
)}
|
|
242
|
+
{list}
|
|
243
|
+
</Stack>
|
|
244
|
+
);
|
|
245
|
+
}
|
package/src/mu/TabBox.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Utils } from '@etsoo/shared';
|
|
1
2
|
import { Box, BoxProps, Tab, TabProps, Tabs, TabsProps } from '@mui/material';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
|
|
@@ -8,7 +9,7 @@ export interface TabBoxPanel extends Omit<TabProps, 'value' | 'children'> {
|
|
|
8
9
|
/**
|
|
9
10
|
* Children
|
|
10
11
|
*/
|
|
11
|
-
children?: React.ReactNode;
|
|
12
|
+
children?: ((visible: boolean) => React.ReactNode) | React.ReactNode;
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Panel box props
|
|
@@ -76,7 +77,7 @@ export function TabBox(props: TabBoxPros) {
|
|
|
76
77
|
</Box>
|
|
77
78
|
{tabs.map(({ children, panel }, index) => (
|
|
78
79
|
<Box key={index} hidden={value !== index} {...panel}>
|
|
79
|
-
{children}
|
|
80
|
+
{Utils.getResult(children, value === index)}
|
|
80
81
|
</Box>
|
|
81
82
|
))}
|
|
82
83
|
</React.Fragment>
|