@etsoo/materialui 1.5.71 → 1.5.73

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.
Files changed (61) hide show
  1. package/__tests__/ReactAppTests.tsx +12 -7
  2. package/__tests__/{ResponsePage.tsx → ResponsivePage.tsx} +11 -5
  3. package/__tests__/SelectEx.tsx +1 -1
  4. package/lib/cjs/DataGridEx.d.ts +8 -1
  5. package/lib/cjs/DataGridEx.js +71 -56
  6. package/lib/cjs/DataGridRenderers.d.ts +1 -1
  7. package/lib/cjs/DataGridRenderers.js +1 -1
  8. package/lib/cjs/MUUtils.d.ts +0 -9
  9. package/lib/cjs/MUUtils.js +0 -26
  10. package/lib/cjs/MobileListItemRenderer.d.ts +2 -2
  11. package/lib/cjs/MobileListItemRenderer.js +3 -4
  12. package/lib/cjs/ResponsibleContainer.d.ts +9 -13
  13. package/lib/cjs/ResponsibleContainer.js +19 -58
  14. package/lib/cjs/ScrollerListEx.d.ts +23 -23
  15. package/lib/cjs/ScrollerListEx.js +32 -84
  16. package/lib/cjs/TableEx.d.ts +7 -0
  17. package/lib/cjs/TableEx.js +6 -12
  18. package/lib/cjs/pages/DataGridPage.js +3 -32
  19. package/lib/cjs/pages/FixedListPage.js +5 -34
  20. package/lib/cjs/pages/ListPage.js +1 -29
  21. package/lib/cjs/pages/ResponsivePage.d.ts +9 -13
  22. package/lib/cjs/uses/useGridCacheInitLoad.d.ts +2 -0
  23. package/lib/cjs/uses/useGridCacheInitLoad.js +41 -0
  24. package/lib/cjs/uses/useListCacheInitLoad.d.ts +2 -0
  25. package/lib/cjs/uses/useListCacheInitLoad.js +38 -0
  26. package/lib/mjs/DataGridEx.d.ts +8 -1
  27. package/lib/mjs/DataGridEx.js +71 -56
  28. package/lib/mjs/DataGridRenderers.d.ts +1 -1
  29. package/lib/mjs/DataGridRenderers.js +1 -1
  30. package/lib/mjs/MUUtils.d.ts +0 -9
  31. package/lib/mjs/MUUtils.js +0 -26
  32. package/lib/mjs/MobileListItemRenderer.d.ts +2 -2
  33. package/lib/mjs/MobileListItemRenderer.js +3 -4
  34. package/lib/mjs/ResponsibleContainer.d.ts +9 -13
  35. package/lib/mjs/ResponsibleContainer.js +19 -58
  36. package/lib/mjs/ScrollerListEx.d.ts +23 -23
  37. package/lib/mjs/ScrollerListEx.js +32 -84
  38. package/lib/mjs/TableEx.d.ts +7 -0
  39. package/lib/mjs/TableEx.js +6 -12
  40. package/lib/mjs/pages/DataGridPage.js +3 -32
  41. package/lib/mjs/pages/FixedListPage.js +5 -34
  42. package/lib/mjs/pages/ListPage.js +1 -29
  43. package/lib/mjs/pages/ResponsivePage.d.ts +9 -13
  44. package/lib/mjs/uses/useGridCacheInitLoad.d.ts +2 -0
  45. package/lib/mjs/uses/useGridCacheInitLoad.js +35 -0
  46. package/lib/mjs/uses/useListCacheInitLoad.d.ts +2 -0
  47. package/lib/mjs/uses/useListCacheInitLoad.js +32 -0
  48. package/package.json +18 -19
  49. package/src/DataGridEx.tsx +155 -109
  50. package/src/DataGridRenderers.tsx +2 -1
  51. package/src/MUUtils.ts +0 -33
  52. package/src/MobileListItemRenderer.tsx +4 -4
  53. package/src/ResponsibleContainer.tsx +50 -111
  54. package/src/ScrollerListEx.tsx +141 -229
  55. package/src/TableEx.tsx +20 -12
  56. package/src/pages/DataGridPage.tsx +3 -49
  57. package/src/pages/FixedListPage.tsx +5 -49
  58. package/src/pages/ListPage.tsx +0 -43
  59. package/src/pages/ResponsivePage.tsx +16 -21
  60. package/src/uses/useGridCacheInitLoad.ts +55 -0
  61. package/src/uses/useListCacheInitLoad.ts +51 -0
@@ -4,7 +4,9 @@ import { ScrollerList } from "@etsoo/react";
4
4
  import { Utils } from "@etsoo/shared";
5
5
  import React from "react";
6
6
  import { MUGlobal } from "./MUGlobal";
7
- import { useTheme } from "@mui/material/styles";
7
+ import { GridUtils } from "./GridUtils";
8
+ import { useListCacheInitLoad } from "./uses/useListCacheInitLoad";
9
+ import Box from "@mui/material/Box";
8
10
  // Scroll bar size
9
11
  const scrollbarSize = 16;
10
12
  // Selected class name
@@ -39,28 +41,9 @@ const createGridStyle = (alternatingColors, selectedColor) => {
39
41
  }
40
42
  });
41
43
  };
42
- // Default margin
43
- // horizon: null means full horizontal margin, -1 means all half, >=0 means left/right
44
- const defaultMargin = (margin, horizon) => {
45
- const half = MUGlobal.half(margin);
46
- if (horizon == null) {
47
- const half = MUGlobal.half(margin);
48
- return {
49
- marginLeft: margin,
50
- marginRight: margin,
51
- marginTop: half,
52
- marginBottom: half
53
- };
54
- }
55
- if ((typeof horizon === "number" && horizon >= 0) ||
56
- (typeof horizon === "string" && /^-?\d+/.test(horizon))) {
57
- return {
58
- marginLeft: horizon,
59
- marginRight: horizon,
60
- marginTop: half,
61
- marginBottom: half
62
- };
63
- }
44
+ // Default margins
45
+ const defaultMargins = () => {
46
+ const half = MUGlobal.half(MUGlobal.pagePaddings);
64
47
  return {
65
48
  marginLeft: half,
66
49
  marginRight: half,
@@ -68,24 +51,6 @@ const defaultMargin = (margin, horizon) => {
68
51
  marginBottom: half
69
52
  };
70
53
  };
71
- // Default itemRenderer
72
- function defaultItemRenderer({ index, innerItemRenderer, data, onMouseDown, selected, style, itemHeight, onClick, onDoubleClick, space, margins }) {
73
- // Child
74
- const child = innerItemRenderer({
75
- index,
76
- data,
77
- style,
78
- selected,
79
- itemHeight,
80
- space,
81
- margins
82
- });
83
- let rowClass = `ScrollerListEx-Row${index % 2}`;
84
- if (selected)
85
- rowClass += ` ${selectedClassName}`;
86
- // Layout
87
- return (_jsx("div", { className: rowClass, style: style, onMouseDown: (event) => onMouseDown(event.currentTarget, data), onClick: (event) => onClick && onClick(event, data), onDoubleClick: (event) => onDoubleClick && onDoubleClick(event, data), children: child }));
88
- }
89
54
  /**
90
55
  * Extended ScrollerList
91
56
  * @param props Props
@@ -113,48 +78,31 @@ export function ScrollerListEx(props) {
113
78
  return selected;
114
79
  };
115
80
  // Destruct
116
- const { alternatingColors = [undefined, undefined], className, idField = "id", innerItemRenderer, itemSize, itemRenderer = (itemProps) => {
117
- const [itemHeight, space, margins] = calculateItemSize(itemProps.index);
118
- return defaultItemRenderer({
119
- itemHeight,
120
- innerItemRenderer,
121
- onMouseDown,
122
- onClick,
123
- onDoubleClick,
124
- space,
125
- margins,
126
- selected: isSelected(itemProps.data),
127
- ...itemProps
128
- });
129
- }, onClick, onDoubleClick, onSelectChange, selectedColor = "#edf4fb", ...rest } = props;
130
- // Theme
131
- const theme = useTheme();
132
- // Cache calculation
133
- const itemSizeResult = React.useMemo(() => {
134
- if (typeof itemSize === "function")
135
- return undefined;
136
- const [size, spaces, h] = itemSize;
137
- if (typeof spaces === "number")
138
- return [size, spaces, defaultMargin(MUGlobal.pagePaddings, undefined)];
139
- return [size, MUGlobal.getSpace(spaces, theme), defaultMargin(spaces, h)];
140
- }, [itemSize]);
141
- // Calculate size
142
- const calculateItemSize = (index) => {
143
- // Callback function
144
- if (typeof itemSize === "function") {
145
- const result = itemSize(index);
146
- if (result.length == 2)
147
- return [...result, defaultMargin(MUGlobal.pagePaddings)];
148
- return result;
149
- }
150
- // Calculation
151
- return itemSizeResult;
152
- };
153
- // Local item size
154
- const itemSizeLocal = (index) => {
155
- const [size, space] = calculateItemSize(index);
156
- return size + space;
157
- };
81
+ const { alternatingColors = [undefined, undefined], className, cacheKey, cacheMinutes = 15, cellMargins = defaultMargins(), idField = "id", itemRenderer = ({ data, margins, style }) => (_jsx(Box, { component: "pre", sx: {
82
+ ...margins
83
+ }, style: style, children: JSON.stringify(data) })), onClick, onDoubleClick, onUpdateRows, onSelectChange, rowHeight = 116, selectedColor = "#edf4fb", ...rest } = props;
84
+ // Init handler
85
+ const initHandler = useListCacheInitLoad(cacheKey, cacheMinutes);
86
+ const onUpdateRowsHandler = React.useCallback((rows, state) => {
87
+ GridUtils.getUpdateRowsHandler(cacheKey)?.(rows, state);
88
+ onUpdateRows?.(rows, state);
89
+ }, [onUpdateRows, cacheKey]);
158
90
  // Layout
159
- return (_jsx(ScrollerList, { className: Utils.mergeClasses("ScrollerListEx-Body", className, createGridStyle(alternatingColors, selectedColor)), idField: idField, itemRenderer: itemRenderer, itemSize: itemSizeLocal, ...rest }));
91
+ return (_jsx(ScrollerList, { className: Utils.mergeClasses("ScrollerListEx-Body", className, createGridStyle(alternatingColors, selectedColor)), idField: idField, onRowsRendered: cacheKey
92
+ ? (visibleRows) => sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(visibleRows))
93
+ : undefined, onInitLoad: initHandler, onUpdateRows: onUpdateRowsHandler, rowComponent: (cellProps) => {
94
+ const { index, style, items } = cellProps;
95
+ const data = items[index];
96
+ const selected = isSelected(data);
97
+ const rowClass = `ScrollerListEx-Row${index % 2}${selected ? ` ${selectedClassName}` : ""}`;
98
+ // Child
99
+ const child = itemRenderer({
100
+ index,
101
+ data,
102
+ style,
103
+ selected,
104
+ margins: cellMargins
105
+ });
106
+ return (_jsx("div", { className: rowClass, style: style, onMouseDown: (event) => onMouseDown(event.currentTarget, data), onClick: (event) => onClick && onClick(event, data), onDoubleClick: (event) => onDoubleClick && onDoubleClick(event, data), children: child }));
107
+ }, rowHeight: rowHeight, ...rest }));
160
108
  }
@@ -43,6 +43,13 @@ export type TableExProps<T extends object, D extends DataTypes.Keys<T>> = TableP
43
43
  * Methods
44
44
  */
45
45
  mRef?: React.Ref<TableExMethodRef<T>>;
46
+ /**
47
+ * Data change handler
48
+ * @param rows Rows
49
+ * @param rowIndex Row index
50
+ * @param columnIndex Column index
51
+ */
52
+ onDataChange?: (rows: T[], rowIndex: number, columnIndex: number) => void;
46
53
  /**
47
54
  * On items select change
48
55
  */
@@ -27,7 +27,7 @@ export function TableEx(props) {
27
27
  // Theme
28
28
  const theme = useTheme();
29
29
  // Destruct
30
- const { alternatingColors = [theme.palette.action.hover, undefined], autoLoad = true, columns, defaultOrderBy, headerColors = [undefined, undefined], idField = "id", loadBatchSize, loadData, maxHeight, mRef, onSelectChange, rowHeight = 53, otherHeight = 110, threshold, ...rest } = props;
30
+ const { alternatingColors = [theme.palette.action.hover, undefined], autoLoad = true, columns, defaultOrderBy, headerColors = [undefined, undefined], idField = "id", loadBatchSize, loadData, maxHeight, mRef, onDataChange, onSelectChange, rowHeight = 53, otherHeight = 110, threshold, ...rest } = props;
31
31
  const selectable = onSelectChange != null;
32
32
  // Rows per page
33
33
  let rowsPerPageLocal;
@@ -83,6 +83,9 @@ export function TableEx(props) {
83
83
  });
84
84
  };
85
85
  React.useImperativeHandle(mRef, () => ({
86
+ get element() {
87
+ return null;
88
+ },
86
89
  delete(index) {
87
90
  const item = rows.at(index);
88
91
  if (item) {
@@ -97,20 +100,11 @@ export function TableEx(props) {
97
100
  newRows.splice(start, 0, item);
98
101
  setRows(newRows);
99
102
  },
100
- /**
101
- * Refresh data
102
- */
103
103
  refresh() {
104
104
  loadDataLocal();
105
105
  },
106
- /**
107
- * Reset
108
- */
109
106
  reset,
110
- scrollToRef(scrollOffset) {
111
- // Not implemented
112
- },
113
- scrollToItemRef(index) {
107
+ scrollToRow(param) {
114
108
  // Not implemented
115
109
  }
116
110
  }), []);
@@ -284,7 +278,7 @@ export function TableEx(props) {
284
278
  rowIndex,
285
279
  columnIndex,
286
280
  cellProps,
287
- setItems
281
+ triggerChange: () => onDataChange?.(rows, rowIndex, columnIndex)
288
282
  })) : (_jsx(React.Fragment, { children: "\u00A0" }));
289
283
  return (_jsx(TableCell, { ...cellProps, children: child }, `${rowId}${columnIndex}`));
290
284
  })] }, rowId));
@@ -27,9 +27,10 @@ export function DataGridPage(props) {
27
27
  if (ref == null)
28
28
  return;
29
29
  states.ref = ref;
30
+ if (ref.element)
31
+ setStates({ element: ref.element });
30
32
  //setStates({ ref });
31
33
  });
32
- const initLoadedRef = React.useRef(null);
33
34
  // On submit callback
34
35
  const onSubmit = (data, _reset) => {
35
36
  setStates({ data });
@@ -39,33 +40,6 @@ export function DataGridPage(props) {
39
40
  };
40
41
  // Search data
41
42
  const searchData = useSearchParamsWithCache(cacheKey);
42
- const onInitLoad = (ref) => {
43
- // Avoid repeatedly load from cache
44
- if (initLoadedRef.current || !cacheKey)
45
- return undefined;
46
- // Cache data
47
- const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
48
- if (cacheData) {
49
- const { rows, state } = cacheData;
50
- GridUtils.mergeSearchData(state, searchData);
51
- // Scroll position
52
- const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
53
- if (scrollData) {
54
- const { scrollLeft, scrollTop } = JSON.parse(scrollData);
55
- globalThis.setTimeout(() => ref.scrollTo({ scrollLeft, scrollTop }), 0);
56
- }
57
- // Update flag value
58
- initLoadedRef.current = true;
59
- // Return cached rows and state
60
- return [rows, state];
61
- }
62
- return undefined;
63
- };
64
- const onGridScroll = (props) => {
65
- if (!cacheKey || !initLoadedRef.current)
66
- return;
67
- sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
68
- };
69
43
  // Watch container
70
44
  const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
71
45
  const rect = dimensions[0][2];
@@ -90,10 +64,7 @@ export function DataGridPage(props) {
90
64
  const gridHeight = states.height;
91
65
  if (gridHeight == null)
92
66
  return;
93
- return (_jsx(DataGridEx, { autoLoad: false, height: gridHeight, loadData: localLoadData, mRef: refs, onUpdateRows: GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, onScroll: onGridScroll, outerRef: (element) => {
94
- if (element != null)
95
- setStates({ element });
96
- }, ...rest }));
67
+ return (_jsx(DataGridEx, { autoLoad: false, height: gridHeight, loadData: localLoadData, mRef: refs, ...rest }));
97
68
  }, [states.height]);
98
69
  const { ref, data } = states;
99
70
  React.useEffect(() => {
@@ -19,7 +19,6 @@ export function FixedListPage(props) {
19
19
  pageProps.paddings ??= MUGlobal.pagePaddings;
20
20
  // States
21
21
  const [states] = React.useState({});
22
- const initLoadedRef = React.useRef(null);
23
22
  // Scroll container
24
23
  const [scrollContainer, updateScrollContainer] = React.useState();
25
24
  const refs = useCombinedRefs(mRef, (ref) => {
@@ -27,6 +26,8 @@ export function FixedListPage(props) {
27
26
  return;
28
27
  const first = states.ref == null;
29
28
  states.ref = ref;
29
+ if (ref.element)
30
+ updateScrollContainer(ref.element);
30
31
  if (first)
31
32
  reset();
32
33
  });
@@ -43,35 +44,6 @@ export function FixedListPage(props) {
43
44
  const localLoadData = (props, lastItem) => {
44
45
  return loadData(GridUtils.createLoader(props, fieldTemplate, cacheKey, false), lastItem);
45
46
  };
46
- // Search data
47
- const searchData = useSearchParamsWithCache(cacheKey);
48
- const onInitLoad = (ref) => {
49
- // Avoid repeatedly load from cache
50
- if (initLoadedRef.current || !cacheKey)
51
- return undefined;
52
- // Cache data
53
- const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
54
- if (cacheData) {
55
- const { rows, state } = cacheData;
56
- GridUtils.mergeSearchData(state, searchData);
57
- // Scroll position
58
- const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
59
- if (scrollData) {
60
- const { scrollOffset } = JSON.parse(scrollData);
61
- globalThis.setTimeout(() => ref.scrollTo(scrollOffset), 0);
62
- }
63
- // Update flag value
64
- initLoadedRef.current = true;
65
- // Return cached rows and state
66
- return [rows, state];
67
- }
68
- return undefined;
69
- };
70
- const onListScroll = (props) => {
71
- if (!cacheKey || !initLoadedRef.current)
72
- return;
73
- sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
74
- };
75
47
  // Watch container
76
48
  const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
77
49
  const rect = dimensions[0][2];
@@ -86,12 +58,11 @@ export function FixedListPage(props) {
86
58
  : adjustHeight(height, rect);
87
59
  return (_jsx(Box, { id: "list-container", sx: {
88
60
  height: height + "px"
89
- }, children: _jsx(ScrollerListEx, { autoLoad: false, height: height, loadData: localLoadData, mRef: refs, onUpdateRows: GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, onScroll: onListScroll, oRef: (element) => {
90
- if (element != null)
91
- updateScrollContainer(element);
92
- }, ...rest }) }));
61
+ }, children: _jsx(ScrollerListEx, { autoLoad: false, height: height, loadData: localLoadData, mRef: refs, ...rest }) }));
93
62
  }
94
63
  }, [rect]);
64
+ // Search data
65
+ const searchData = useSearchParamsWithCache(cacheKey);
95
66
  const f = typeof fields == "function" ? fields(searchData ?? {}) : fields;
96
67
  const { paddings, ...pageRest } = pageProps;
97
68
  // Layout
@@ -27,7 +27,6 @@ export function ListPage(props) {
27
27
  if (first)
28
28
  reset();
29
29
  });
30
- const initLoadedRef = React.useRef(null);
31
30
  const reset = () => {
32
31
  if (states.data == null || states.ref == null)
33
32
  return;
@@ -46,36 +45,9 @@ export function ListPage(props) {
46
45
  const rect = dimensions[0][2];
47
46
  // Search data
48
47
  const searchData = useSearchParamsWithCache(cacheKey);
49
- const onInitLoad = (ref) => {
50
- // Avoid repeatedly load from cache
51
- if (initLoadedRef.current || !cacheKey)
52
- return undefined;
53
- // Cache data
54
- const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
55
- if (cacheData) {
56
- const { rows, state } = cacheData;
57
- GridUtils.mergeSearchData(state, searchData);
58
- // Scroll position
59
- const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
60
- if (scrollData) {
61
- const { scrollOffset } = JSON.parse(scrollData);
62
- globalThis.setTimeout(() => ref.scrollTo(scrollOffset), 0);
63
- }
64
- // Update flag value
65
- initLoadedRef.current = true;
66
- // Return cached rows and state
67
- return [rows, state];
68
- }
69
- return undefined;
70
- };
71
- const onListScroll = (props) => {
72
- if (!cacheKey || !initLoadedRef.current)
73
- return;
74
- sessionStorage.setItem(`${cacheKey}-scroll`, JSON.stringify(props));
75
- };
76
48
  const f = typeof fields == "function" ? fields(searchData ?? {}) : fields;
77
49
  // Layout
78
50
  return (_jsx(CommonPage, { ...pageProps, scrollContainer: globalThis, children: _jsxs(Stack, { children: [_jsx(Box, { ref: dimensions[0][0], sx: {
79
51
  paddingBottom: pageProps.paddings
80
- }, children: rect && rect.width > 100 && (_jsx(SearchBar, { fields: f, onSubmit: onSubmit, top: searchBarTop, width: rect.width })) }), _jsx(ScrollerListEx, { autoLoad: false, loadData: localLoadData, onUpdateRows: GridUtils.getUpdateRowsHandler(cacheKey), onInitLoad: onInitLoad, onScroll: onListScroll, mRef: refs, ...rest })] }) }));
52
+ }, children: rect && rect.width > 100 && (_jsx(SearchBar, { fields: f, onSubmit: onSubmit, top: searchBarTop, width: rect.width })) }), _jsx(ScrollerListEx, { autoLoad: false, loadData: localLoadData, mRef: refs, ...rest })] }) }));
81
53
  }
@@ -1,13 +1,13 @@
1
1
  import React from "react";
2
+ import { ResponsibleContainerProps } from "../ResponsibleContainer";
2
3
  import type { DataGridPageProps } from "./DataGridPageProps";
3
- import type { ScrollerListExInnerItemRendererProps, ScrollerListExItemSize } from "../ScrollerListEx";
4
- import { ListChildComponentProps } from "react-window";
4
+ import type { ScrollerListExProps } from "../ScrollerListEx";
5
5
  import { GridMethodRef } from "@etsoo/react";
6
6
  import type { OperationMessageHandlerAll } from "../messages/OperationMessageHandler";
7
7
  /**
8
8
  * Response page props
9
9
  */
10
- export type ResponsePageProps<T extends object, F> = DataGridPageProps<T, F> & {
10
+ export type ResponsePageProps<T extends object, F> = Omit<DataGridPageProps<T, F>, "mRef" | "rowHeight"> & {
11
11
  /**
12
12
  *
13
13
  * @param height Current height
@@ -19,22 +19,14 @@ export type ResponsePageProps<T extends object, F> = DataGridPageProps<T, F> & {
19
19
  * Min width to show Datagrid
20
20
  */
21
21
  dataGridMinWidth?: number;
22
- /**
23
- * Inner item renderer
24
- */
25
- innerItemRenderer: (props: ScrollerListExInnerItemRendererProps<T>) => React.ReactNode;
26
22
  /**
27
23
  * Item renderer
28
24
  */
29
- itemRenderer?: (props: ListChildComponentProps<T>) => React.ReactElement;
30
- /**
31
- * Item size, a function indicates its a variable size list
32
- */
33
- itemSize: ScrollerListExItemSize;
25
+ itemRenderer?: ScrollerListExProps<T>["itemRenderer"];
34
26
  /**
35
27
  * Methods
36
28
  */
37
- mRef?: React.MutableRefObject<GridMethodRef<T> | undefined>;
29
+ mRef?: React.RefObject<GridMethodRef<T> | undefined>;
38
30
  /**
39
31
  * Pull to refresh data
40
32
  */
@@ -47,6 +39,10 @@ export type ResponsePageProps<T extends object, F> = DataGridPageProps<T, F> & {
47
39
  * Operation message handler
48
40
  */
49
41
  operationMessageHandler?: OperationMessageHandlerAll;
42
+ /**
43
+ * Row height
44
+ */
45
+ rowHeight?: ResponsibleContainerProps<T, F>["rowHeight"];
50
46
  };
51
47
  /**
52
48
  * Fixed height list page
@@ -0,0 +1,2 @@
1
+ import { ScrollerGridProps } from "@etsoo/react";
2
+ export declare function useGridCacheInitLoad<T extends object>(cacheKey: string | undefined, cacheMinutes: number): ScrollerGridProps<T>["onInitLoad"];
@@ -0,0 +1,35 @@
1
+ import { useSearchParamsWithCache } from "@etsoo/react";
2
+ import React from "react";
3
+ import { GridUtils } from "../GridUtils";
4
+ import { ExtendUtils } from "@etsoo/shared";
5
+ export function useGridCacheInitLoad(cacheKey, cacheMinutes) {
6
+ // Reference
7
+ const ref = React.useRef(null);
8
+ // Search data
9
+ const searchData = useSearchParamsWithCache(cacheKey);
10
+ // Avoid repeatedly load from cache
11
+ if (ref.current || !cacheKey)
12
+ return undefined;
13
+ // Cache data
14
+ const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
15
+ if (cacheData) {
16
+ const { rows, state } = cacheData;
17
+ GridUtils.mergeSearchData(state, searchData);
18
+ // Update flag value
19
+ ref.current = true;
20
+ return (ref) => {
21
+ // Scroll position
22
+ const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
23
+ if (scrollData) {
24
+ const data = JSON.parse(scrollData);
25
+ ExtendUtils.waitFor(() => ref.scrollToCell({
26
+ rowIndex: data.rowStartIndex,
27
+ columnIndex: data.columnStartIndex
28
+ }), 100);
29
+ }
30
+ // Return cached rows and state
31
+ return [rows, state];
32
+ };
33
+ }
34
+ return undefined;
35
+ }
@@ -0,0 +1,2 @@
1
+ import { ScrollerListProps } from "@etsoo/react";
2
+ export declare function useListCacheInitLoad<T extends object>(cacheKey: string | undefined, cacheMinutes: number): ScrollerListProps<T>["onInitLoad"];
@@ -0,0 +1,32 @@
1
+ import { useSearchParamsWithCache } from "@etsoo/react";
2
+ import React from "react";
3
+ import { GridUtils } from "../GridUtils";
4
+ import { ExtendUtils } from "@etsoo/shared";
5
+ export function useListCacheInitLoad(cacheKey, cacheMinutes) {
6
+ // Reference
7
+ const ref = React.useRef(null);
8
+ // Search data
9
+ const searchData = useSearchParamsWithCache(cacheKey);
10
+ // Avoid repeatedly load from cache
11
+ if (ref.current || !cacheKey)
12
+ return undefined;
13
+ // Cache data
14
+ const cacheData = GridUtils.getCacheData(cacheKey, cacheMinutes);
15
+ if (cacheData) {
16
+ const { rows, state } = cacheData;
17
+ GridUtils.mergeSearchData(state, searchData);
18
+ // Update flag value
19
+ ref.current = true;
20
+ return (ref) => {
21
+ // Scroll position
22
+ const scrollData = sessionStorage.getItem(`${cacheKey}-scroll`);
23
+ if (scrollData) {
24
+ const data = JSON.parse(scrollData);
25
+ ExtendUtils.waitFor(() => ref.scrollToRow({ index: data.startIndex }), 100);
26
+ }
27
+ // Return cached rows and state
28
+ return [rows, state];
29
+ };
30
+ }
31
+ return undefined;
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.5.71",
3
+ "version": "1.5.73",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -40,23 +40,23 @@
40
40
  "@dnd-kit/sortable": "^10.0.0",
41
41
  "@emotion/react": "^11.14.0",
42
42
  "@emotion/styled": "^11.14.1",
43
- "@etsoo/appscript": "^1.6.43",
44
- "@etsoo/notificationbase": "^1.1.63",
45
- "@etsoo/react": "^1.8.51",
46
- "@etsoo/shared": "^1.2.75",
47
- "@mui/icons-material": "^7.3.1",
48
- "@mui/material": "^7.3.1",
49
- "@mui/x-data-grid": "^8.10.1",
43
+ "@etsoo/appscript": "^1.6.45",
44
+ "@etsoo/notificationbase": "^1.1.64",
45
+ "@etsoo/react": "^1.8.59",
46
+ "@etsoo/shared": "^1.2.76",
47
+ "@mui/icons-material": "^7.3.4",
48
+ "@mui/material": "^7.3.4",
49
+ "@mui/x-data-grid": "^8.14.0",
50
50
  "chart.js": "^4.5.0",
51
51
  "chartjs-plugin-datalabels": "^2.2.0",
52
- "dompurify": "^3.2.6",
52
+ "dompurify": "^3.2.7",
53
53
  "eventemitter3": "^5.0.1",
54
54
  "pica": "^9.0.1",
55
55
  "pulltorefreshjs": "^0.1.22",
56
- "react": "^19.1.1",
56
+ "react": "^19.2.0",
57
57
  "react-avatar-editor": "^13.0.2",
58
58
  "react-chartjs-2": "^5.3.0",
59
- "react-dom": "^19.1.1",
59
+ "react-dom": "^19.2.0",
60
60
  "react-draggable": "^4.5.0",
61
61
  "react-imask": "7.6.1"
62
62
  },
@@ -67,23 +67,22 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@babel/cli": "^7.28.3",
70
- "@babel/core": "^7.28.3",
70
+ "@babel/core": "^7.28.4",
71
71
  "@babel/plugin-transform-runtime": "^7.28.3",
72
72
  "@babel/preset-env": "^7.28.3",
73
73
  "@babel/preset-react": "^7.27.1",
74
74
  "@babel/preset-typescript": "^7.27.1",
75
- "@babel/runtime-corejs3": "^7.28.3",
75
+ "@babel/runtime-corejs3": "^7.28.4",
76
76
  "@testing-library/react": "^16.3.0",
77
77
  "@types/pica": "^9.0.5",
78
78
  "@types/pulltorefreshjs": "^0.1.7",
79
- "@types/react": "^19.1.10",
79
+ "@types/react": "^19.2.2",
80
80
  "@types/react-avatar-editor": "^13.0.4",
81
- "@types/react-dom": "^19.1.7",
81
+ "@types/react-dom": "^19.2.1",
82
82
  "@types/react-input-mask": "^3.0.6",
83
- "@types/react-window": "^1.8.8",
84
- "@vitejs/plugin-react": "^5.0.1",
85
- "jsdom": "^26.1.0",
86
- "typescript": "^5.9.2",
83
+ "@vitejs/plugin-react": "^5.0.4",
84
+ "jsdom": "^27.0.0",
85
+ "typescript": "^5.9.3",
87
86
  "vitest": "^3.2.4"
88
87
  }
89
88
  }