@etsoo/react 1.4.31 → 1.4.35

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.
@@ -36,7 +36,7 @@ export const ScrollerGrid = (props) => {
36
36
  // Update state
37
37
  state.isNextPageLoading = true;
38
38
  // Parameters
39
- const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } = state;
39
+ const { currentPage, batchSize, orderBy, orderByAsc, data } = state;
40
40
  const loadProps = {
41
41
  currentPage,
42
42
  batchSize,
@@ -45,10 +45,10 @@ export const ScrollerGrid = (props) => {
45
45
  data
46
46
  };
47
47
  loadData(loadProps).then((result) => {
48
- state.isMounted = true;
49
- if (result == null || isMounted === false) {
48
+ if (result == null || state.isMounted === false) {
50
49
  return;
51
50
  }
51
+ state.isMounted = true;
52
52
  const newItems = result.length;
53
53
  state.lastLoadedItems = newItems;
54
54
  state.isNextPageLoading = false;
@@ -109,7 +109,8 @@ export const ScrollerGrid = (props) => {
109
109
  };
110
110
  Object.assign(state, resetState);
111
111
  // Reset items
112
- setRows([]);
112
+ if (state.isMounted !== false)
113
+ setRows([]);
113
114
  };
114
115
  React.useImperativeHandle(mRef, () => ({
115
116
  scrollTo(params) {
@@ -184,13 +185,12 @@ export const ScrollerGrid = (props) => {
184
185
  shouldForceUpdate: true
185
186
  });
186
187
  }, [width]);
187
- // Destruct state
188
- const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
188
+ // Rows
189
189
  const rowLength = rows.length;
190
190
  // Row count
191
- const rowCount = hasNextPage ? rowLength + 1 : rowLength;
191
+ const rowCount = state.hasNextPage ? rowLength + 1 : rowLength;
192
192
  // Auto load data when current page is 0
193
- if (currentPage === 0 && stateAutoLoad)
193
+ if (state.currentPage === 0 && state.autoLoad)
194
194
  loadDataLocal();
195
195
  // Layout
196
196
  return (React.createElement(React.Fragment, null,
@@ -53,7 +53,7 @@ export const ScrollerList = (props) => {
53
53
  // Update state
54
54
  state.isNextPageLoading = true;
55
55
  // Parameters
56
- const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } = state;
56
+ const { currentPage, batchSize, orderBy, orderByAsc, data } = state;
57
57
  const loadProps = {
58
58
  currentPage,
59
59
  batchSize,
@@ -62,10 +62,10 @@ export const ScrollerList = (props) => {
62
62
  data
63
63
  };
64
64
  loadData(loadProps).then((result) => {
65
- state.isMounted = true;
66
- if (result == null || isMounted === false) {
65
+ if (result == null || state.isMounted === false) {
67
66
  return;
68
67
  }
68
+ state.isMounted = true;
69
69
  const newItems = result.length;
70
70
  state.lastLoadedItems = newItems;
71
71
  state.hasNextPage = newItems >= loadBatchSize;
@@ -121,7 +121,8 @@ export const ScrollerList = (props) => {
121
121
  };
122
122
  Object.assign(state, resetState);
123
123
  // Reset
124
- setRows([]);
124
+ if (state.isMounted !== false)
125
+ setRows([]);
125
126
  },
126
127
  scrollTo(scrollOffset) {
127
128
  refMethods.scrollTo(scrollOffset);
@@ -160,8 +161,7 @@ export const ScrollerList = (props) => {
160
161
  state.isMounted = false;
161
162
  };
162
163
  }, []);
163
- // Destruct state
164
- const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
164
+ // Row count
165
165
  const rowCount = rows.length;
166
166
  // Local items renderer callback
167
167
  const onItemsRenderedLocal = (props) => {
@@ -175,9 +175,9 @@ export const ScrollerList = (props) => {
175
175
  onItemsRendered(props);
176
176
  };
177
177
  // Item count
178
- const itemCount = hasNextPage ? rowCount + 1 : rowCount;
178
+ const itemCount = state.hasNextPage ? rowCount + 1 : rowCount;
179
179
  // Auto load data when current page is 0
180
- if (currentPage === 0 && stateAutoLoad)
180
+ if (state.currentPage === 0 && state.autoLoad)
181
181
  loadDataLocal();
182
182
  // Layout
183
183
  return typeof itemSize === 'function' ? (React.createElement(VariableSizeList, { height: height, width: width, itemCount: itemCount, itemSize: itemSize, outerRef: refs, ref: listRef, style: style, onItemsRendered: onItemsRenderedLocal, ...rest }, itemRendererLocal)) : (React.createElement(FixedSizeList, { height: height, width: width, itemCount: itemCount, itemSize: itemSize, outerRef: refs, ref: listRef, style: style, onItemsRendered: onItemsRenderedLocal, ...rest }, itemRendererLocal));
@@ -67,7 +67,7 @@ export var DataGridRenderers;
67
67
  if (value)
68
68
  return React.createElement(CheckIcon, { fontSize: "small" });
69
69
  else
70
- return React.createElement(ClearIcon, { fontSize: "small" });
70
+ return React.createElement(ClearIcon, { fontSize: "small", color: "error" });
71
71
  }
72
72
  // To string
73
73
  return new String(value);
@@ -23,7 +23,7 @@ export interface ResponsibleContainerProps<T extends {}, F extends DataTypes.Bas
23
23
  /**
24
24
  * Container box SX (dataGrid determines the case)
25
25
  */
26
- containerBoxSx?: (dataGrid?: boolean) => SxProps<Theme>;
26
+ containerBoxSx?: (paddings: {}, dataGrid?: boolean) => SxProps<Theme>;
27
27
  /**
28
28
  * Min width to show Datagrid
29
29
  */
@@ -9,13 +9,12 @@ import { MUGlobal } from './MUGlobal';
9
9
  import { PullToRefreshUI } from './PullToRefreshUI';
10
10
  import { ScrollerListEx } from './ScrollerListEx';
11
11
  import { SearchBar } from './SearchBar';
12
- function getDefaultSearchBoxSx(paddings) {
12
+ function defaultContainerBoxSx(paddings, _dataGrid) {
13
13
  const half = MUGlobal.half(paddings);
14
14
  return {
15
- paddingLeft: (theme) => theme.spacing(1),
16
- paddingRight: (theme) => theme.spacing(1),
17
- paddingTop: half,
18
- marginBottom: half
15
+ '& .SearchBox': {
16
+ marginBottom: half
17
+ }
19
18
  };
20
19
  }
21
20
  /**
@@ -25,7 +24,7 @@ function getDefaultSearchBoxSx(paddings) {
25
24
  */
26
25
  export function ResponsibleContainer(props) {
27
26
  // Destruct
28
- const { adjustHeight, columns, containerBoxSx, dataGridMinWidth = Math.max(576, DataGridExCalColumns(columns).total), elementReady, fields, fieldTemplate, height, loadData, mRef, paddings = MUGlobal.pagePaddings, pullToRefresh = true, sizeReadyMiliseconds = 0, ...rest } = props;
27
+ const { adjustHeight, columns, containerBoxSx = defaultContainerBoxSx, dataGridMinWidth = Math.max(576, DataGridExCalColumns(columns).total), elementReady, fields, fieldTemplate, height, loadData, mRef, paddings = MUGlobal.pagePaddings, pullToRefresh = true, sizeReadyMiliseconds = 0, ...rest } = props;
29
28
  // Labels
30
29
  const labels = Labels.CommonPage;
31
30
  // Refs
@@ -146,7 +145,7 @@ export function ResponsibleContainer(props) {
146
145
  // Layout
147
146
  return (React.createElement(Box, { sx: containerBoxSx == null
148
147
  ? undefined
149
- : containerBoxSx(showDataGrid) },
148
+ : containerBoxSx(paddings, showDataGrid) },
150
149
  React.createElement(Stack, null,
151
150
  React.createElement(Box, { ref: dimensions[0][0], className: "SearchBox" }, searchBar),
152
151
  list),
@@ -21,6 +21,14 @@ export interface TabBoxPros extends BoxProps {
21
21
  * Container props
22
22
  */
23
23
  container?: Omit<TabsProps, 'value'>;
24
+ /**
25
+ * Default selected index
26
+ */
27
+ defaultIndex?: number;
28
+ /**
29
+ * Current index
30
+ */
31
+ index?: number;
24
32
  /**
25
33
  * Add a hidden input and its name
26
34
  */
package/lib/mu/TabBox.js CHANGED
@@ -8,10 +8,15 @@ import React from 'react';
8
8
  */
9
9
  export function TabBox(props) {
10
10
  // Destruct
11
- const { inputName, root, container = {}, tabs } = props;
11
+ const { index, inputName, root, container = {}, defaultIndex = 0, tabs } = props;
12
12
  const { onChange, ...rest } = container;
13
13
  // State
14
- const [value, setValue] = React.useState(0);
14
+ const [value, setValue] = React.useState(defaultIndex);
15
+ React.useEffect(() => {
16
+ if (index == null)
17
+ return;
18
+ setValue(index);
19
+ }, [index]);
15
20
  // Layout
16
21
  return (React.createElement(React.Fragment, null,
17
22
  inputName && (React.createElement("input", { type: "hidden", name: inputName, value: value })),
@@ -13,13 +13,14 @@ export function ResponsivePage(props) {
13
13
  const { pageProps = {}, ...rest } = props;
14
14
  (_a = pageProps.paddings) !== null && _a !== void 0 ? _a : (pageProps.paddings = MUGlobal.pagePaddings);
15
15
  const { paddings, fabColumnDirection, ...pageRest } = pageProps;
16
- const half = MUGlobal.half(paddings);
17
16
  // State
18
17
  const [scrollContainer, setScrollContainer] = React.useState();
19
18
  const [direction, setDirection] = React.useState(fabColumnDirection);
20
19
  // Layout
21
20
  return (React.createElement(CommonPage, { ...pageRest, paddings: {}, scrollContainer: scrollContainer, fabColumnDirection: direction },
22
- React.createElement(ResponsibleContainer, { paddings: paddings, containerBoxSx: (dataGrid) => {
21
+ React.createElement(ResponsibleContainer, { paddings: paddings, containerBoxSx: (paddings, _dataGrid) => {
22
+ // Half
23
+ const half = MUGlobal.half(paddings);
23
24
  // .SearchBox keep the same to avoid flick when switching between DataGrid and List
24
25
  return {
25
26
  '& .SearchBox': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.4.31",
3
+ "version": "1.4.35",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -198,8 +198,7 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
198
198
  state.isNextPageLoading = true;
199
199
 
200
200
  // Parameters
201
- const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
202
- state;
201
+ const { currentPage, batchSize, orderBy, orderByAsc, data } = state;
203
202
 
204
203
  const loadProps: GridLoadDataProps = {
205
204
  currentPage,
@@ -210,11 +209,10 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
210
209
  };
211
210
 
212
211
  loadData(loadProps).then((result) => {
213
- state.isMounted = true;
214
-
215
- if (result == null || isMounted === false) {
212
+ if (result == null || state.isMounted === false) {
216
213
  return;
217
214
  }
215
+ state.isMounted = true;
218
216
 
219
217
  const newItems = result.length;
220
218
  state.lastLoadedItems = newItems;
@@ -291,7 +289,7 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
291
289
  Object.assign(state, resetState);
292
290
 
293
291
  // Reset items
294
- setRows([]);
292
+ if (state.isMounted !== false) setRows([]);
295
293
  };
296
294
 
297
295
  React.useImperativeHandle(
@@ -378,15 +376,14 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
378
376
  });
379
377
  }, [width]);
380
378
 
381
- // Destruct state
382
- const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
379
+ // Rows
383
380
  const rowLength = rows.length;
384
381
 
385
382
  // Row count
386
- const rowCount = hasNextPage ? rowLength + 1 : rowLength;
383
+ const rowCount = state.hasNextPage ? rowLength + 1 : rowLength;
387
384
 
388
385
  // Auto load data when current page is 0
389
- if (currentPage === 0 && stateAutoLoad) loadDataLocal();
386
+ if (state.currentPage === 0 && state.autoLoad) loadDataLocal();
390
387
 
391
388
  // Layout
392
389
  return (
@@ -163,8 +163,7 @@ export const ScrollerList = <T extends Record<string, any>>(
163
163
  state.isNextPageLoading = true;
164
164
 
165
165
  // Parameters
166
- const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
167
- state;
166
+ const { currentPage, batchSize, orderBy, orderByAsc, data } = state;
168
167
 
169
168
  const loadProps: GridLoadDataProps = {
170
169
  currentPage,
@@ -175,11 +174,10 @@ export const ScrollerList = <T extends Record<string, any>>(
175
174
  };
176
175
 
177
176
  loadData(loadProps).then((result) => {
178
- state.isMounted = true;
179
-
180
- if (result == null || isMounted === false) {
177
+ if (result == null || state.isMounted === false) {
181
178
  return;
182
179
  }
180
+ state.isMounted = true;
183
181
 
184
182
  const newItems = result.length;
185
183
  state.lastLoadedItems = newItems;
@@ -250,7 +248,7 @@ export const ScrollerList = <T extends Record<string, any>>(
250
248
  Object.assign(state, resetState);
251
249
 
252
250
  // Reset
253
- setRows([]);
251
+ if (state.isMounted !== false) setRows([]);
254
252
  },
255
253
 
256
254
  scrollTo(scrollOffset: number): void {
@@ -301,8 +299,7 @@ export const ScrollerList = <T extends Record<string, any>>(
301
299
  };
302
300
  }, []);
303
301
 
304
- // Destruct state
305
- const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
302
+ // Row count
306
303
  const rowCount = rows.length;
307
304
 
308
305
  // Local items renderer callback
@@ -319,10 +316,10 @@ export const ScrollerList = <T extends Record<string, any>>(
319
316
  };
320
317
 
321
318
  // Item count
322
- const itemCount = hasNextPage ? rowCount + 1 : rowCount;
319
+ const itemCount = state.hasNextPage ? rowCount + 1 : rowCount;
323
320
 
324
321
  // Auto load data when current page is 0
325
- if (currentPage === 0 && stateAutoLoad) loadDataLocal();
322
+ if (state.currentPage === 0 && state.autoLoad) loadDataLocal();
326
323
 
327
324
  // Layout
328
325
  return typeof itemSize === 'function' ? (
@@ -103,7 +103,7 @@ export namespace DataGridRenderers {
103
103
  }
104
104
 
105
105
  if (value) return <CheckIcon fontSize="small" />;
106
- else return <ClearIcon fontSize="small" />;
106
+ else return <ClearIcon fontSize="small" color="error" />;
107
107
  }
108
108
 
109
109
  // To string
@@ -54,7 +54,7 @@ export interface ResponsibleContainerProps<
54
54
  /**
55
55
  * Container box SX (dataGrid determines the case)
56
56
  */
57
- containerBoxSx?: (dataGrid?: boolean) => SxProps<Theme>;
57
+ containerBoxSx?: (paddings: {}, dataGrid?: boolean) => SxProps<Theme>;
58
58
 
59
59
  /**
60
60
  * Min width to show Datagrid
@@ -132,13 +132,15 @@ interface LocalRefs {
132
132
  mounted?: boolean;
133
133
  }
134
134
 
135
- function getDefaultSearchBoxSx(paddings: {}): SxProps<Theme> {
135
+ function defaultContainerBoxSx(
136
+ paddings: {},
137
+ _dataGrid?: boolean
138
+ ): SxProps<Theme> {
136
139
  const half = MUGlobal.half(paddings);
137
140
  return {
138
- paddingLeft: (theme) => theme.spacing(1),
139
- paddingRight: (theme) => theme.spacing(1),
140
- paddingTop: half,
141
- marginBottom: half
141
+ '& .SearchBox': {
142
+ marginBottom: half
143
+ }
142
144
  };
143
145
  }
144
146
 
@@ -155,7 +157,7 @@ export function ResponsibleContainer<
155
157
  const {
156
158
  adjustHeight,
157
159
  columns,
158
- containerBoxSx,
160
+ containerBoxSx = defaultContainerBoxSx,
159
161
  dataGridMinWidth = Math.max(576, DataGridExCalColumns(columns).total),
160
162
  elementReady,
161
163
  fields,
@@ -342,7 +344,7 @@ export function ResponsibleContainer<
342
344
  sx={
343
345
  containerBoxSx == null
344
346
  ? undefined
345
- : containerBoxSx(showDataGrid)
347
+ : containerBoxSx(paddings, showDataGrid)
346
348
  }
347
349
  >
348
350
  <Stack>
package/src/mu/TabBox.tsx CHANGED
@@ -26,6 +26,16 @@ export interface TabBoxPros extends BoxProps {
26
26
  */
27
27
  container?: Omit<TabsProps, 'value'>;
28
28
 
29
+ /**
30
+ * Default selected index
31
+ */
32
+ defaultIndex?: number;
33
+
34
+ /**
35
+ * Current index
36
+ */
37
+ index?: number;
38
+
29
39
  /**
30
40
  * Add a hidden input and its name
31
41
  */
@@ -49,11 +59,23 @@ export interface TabBoxPros extends BoxProps {
49
59
  */
50
60
  export function TabBox(props: TabBoxPros) {
51
61
  // Destruct
52
- const { inputName, root, container = {}, tabs } = props;
62
+ const {
63
+ index,
64
+ inputName,
65
+ root,
66
+ container = {},
67
+ defaultIndex = 0,
68
+ tabs
69
+ } = props;
53
70
  const { onChange, ...rest } = container;
54
71
 
55
72
  // State
56
- const [value, setValue] = React.useState(0);
73
+ const [value, setValue] = React.useState(defaultIndex);
74
+
75
+ React.useEffect(() => {
76
+ if (index == null) return;
77
+ setValue(index);
78
+ }, [index]);
57
79
 
58
80
  // Layout
59
81
  return (
@@ -20,8 +20,6 @@ export function ResponsivePage<
20
20
  pageProps.paddings ??= MUGlobal.pagePaddings;
21
21
  const { paddings, fabColumnDirection, ...pageRest } = pageProps;
22
22
 
23
- const half = MUGlobal.half(paddings);
24
-
25
23
  // State
26
24
  const [scrollContainer, setScrollContainer] = React.useState<HTMLElement>();
27
25
  const [direction, setDirection] = React.useState(fabColumnDirection);
@@ -36,7 +34,10 @@ export function ResponsivePage<
36
34
  >
37
35
  <ResponsibleContainer<T, F>
38
36
  paddings={paddings}
39
- containerBoxSx={(dataGrid) => {
37
+ containerBoxSx={(paddings, _dataGrid) => {
38
+ // Half
39
+ const half = MUGlobal.half(paddings);
40
+
40
41
  // .SearchBox keep the same to avoid flick when switching between DataGrid and List
41
42
  return {
42
43
  '& .SearchBox': {