@etsoo/materialui 1.0.1

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 (250) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.json +38 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/main.yml +48 -0
  5. package/.prettierignore +5 -0
  6. package/.prettierrc +6 -0
  7. package/LICENSE +21 -0
  8. package/README.md +16 -0
  9. package/__tests__/ComboBox.tsx +30 -0
  10. package/__tests__/MUGlobalTests.tsx +58 -0
  11. package/__tests__/NotifierMUTests.tsx +217 -0
  12. package/__tests__/SelectEx.tsx +26 -0
  13. package/__tests__/tsconfig.json +19 -0
  14. package/babel.config.json +11 -0
  15. package/lib/AuditDisplay.d.ts +33 -0
  16. package/lib/AuditDisplay.js +52 -0
  17. package/lib/AutocompleteExtendedProps.d.ts +64 -0
  18. package/lib/AutocompleteExtendedProps.js +1 -0
  19. package/lib/BackButton.d.ts +13 -0
  20. package/lib/BackButton.js +33 -0
  21. package/lib/BridgeCloseButton.d.ts +23 -0
  22. package/lib/BridgeCloseButton.js +32 -0
  23. package/lib/ButtonLink.d.ts +17 -0
  24. package/lib/ButtonLink.js +19 -0
  25. package/lib/ComboBox.d.ts +38 -0
  26. package/lib/ComboBox.js +108 -0
  27. package/lib/CountdownButton.d.ts +23 -0
  28. package/lib/CountdownButton.js +81 -0
  29. package/lib/CustomFabProps.d.ts +27 -0
  30. package/lib/CustomFabProps.js +1 -0
  31. package/lib/DataGridEx.d.ts +94 -0
  32. package/lib/DataGridEx.js +329 -0
  33. package/lib/DataGridRenderers.d.ts +22 -0
  34. package/lib/DataGridRenderers.js +99 -0
  35. package/lib/DialogButton.d.ts +54 -0
  36. package/lib/DialogButton.js +45 -0
  37. package/lib/DnDList.d.ts +87 -0
  38. package/lib/DnDList.js +153 -0
  39. package/lib/DraggablePaperComponent.d.ts +8 -0
  40. package/lib/DraggablePaperComponent.js +12 -0
  41. package/lib/EmailInput.d.ts +11 -0
  42. package/lib/EmailInput.js +15 -0
  43. package/lib/FabBox.d.ts +21 -0
  44. package/lib/FabBox.js +31 -0
  45. package/lib/FlexBox.d.ts +14 -0
  46. package/lib/FlexBox.js +18 -0
  47. package/lib/GridDataFormat.d.ts +10 -0
  48. package/lib/GridDataFormat.js +43 -0
  49. package/lib/IconButtonLink.d.ts +17 -0
  50. package/lib/IconButtonLink.js +16 -0
  51. package/lib/InputField.d.ts +21 -0
  52. package/lib/InputField.js +39 -0
  53. package/lib/ItemList.d.ts +56 -0
  54. package/lib/ItemList.js +69 -0
  55. package/lib/ListItemRightIcon.d.ts +4 -0
  56. package/lib/ListItemRightIcon.js +8 -0
  57. package/lib/ListMoreDisplay.d.ts +35 -0
  58. package/lib/ListMoreDisplay.js +99 -0
  59. package/lib/LoadingButton.d.ts +16 -0
  60. package/lib/LoadingButton.js +41 -0
  61. package/lib/MUGlobal.d.ts +102 -0
  62. package/lib/MUGlobal.js +184 -0
  63. package/lib/MaskInput.d.ts +34 -0
  64. package/lib/MaskInput.js +43 -0
  65. package/lib/MobileListItemRenderer.d.ts +17 -0
  66. package/lib/MobileListItemRenderer.js +35 -0
  67. package/lib/MoreFab.d.ts +45 -0
  68. package/lib/MoreFab.js +95 -0
  69. package/lib/NotifierMU.d.ts +47 -0
  70. package/lib/NotifierMU.js +387 -0
  71. package/lib/NotifierPromptProps.d.ts +22 -0
  72. package/lib/NotifierPromptProps.js +1 -0
  73. package/lib/OptionGroup.d.ts +58 -0
  74. package/lib/OptionGroup.js +81 -0
  75. package/lib/PList.d.ts +15 -0
  76. package/lib/PList.js +12 -0
  77. package/lib/ProgressCount.d.ts +44 -0
  78. package/lib/ProgressCount.js +79 -0
  79. package/lib/PullToRefreshUI.d.ts +9 -0
  80. package/lib/PullToRefreshUI.js +18 -0
  81. package/lib/RLink.d.ts +14 -0
  82. package/lib/RLink.js +37 -0
  83. package/lib/ResponsibleContainer.d.ts +87 -0
  84. package/lib/ResponsibleContainer.js +156 -0
  85. package/lib/ScrollTopFab.d.ts +7 -0
  86. package/lib/ScrollTopFab.js +25 -0
  87. package/lib/ScrollerListEx.d.ts +81 -0
  88. package/lib/ScrollerListEx.js +167 -0
  89. package/lib/SearchBar.d.ts +29 -0
  90. package/lib/SearchBar.js +260 -0
  91. package/lib/SearchField.d.ts +21 -0
  92. package/lib/SearchField.js +39 -0
  93. package/lib/SearchOptionGroup.d.ts +9 -0
  94. package/lib/SearchOptionGroup.js +14 -0
  95. package/lib/SelectBool.d.ts +13 -0
  96. package/lib/SelectBool.js +22 -0
  97. package/lib/SelectEx.d.ts +50 -0
  98. package/lib/SelectEx.js +156 -0
  99. package/lib/ShowDataComparison.d.ts +20 -0
  100. package/lib/ShowDataComparison.js +58 -0
  101. package/lib/Switch.d.ts +29 -0
  102. package/lib/Switch.js +34 -0
  103. package/lib/SwitchAnt.d.ts +25 -0
  104. package/lib/SwitchAnt.js +40 -0
  105. package/lib/TabBox.d.ts +54 -0
  106. package/lib/TabBox.js +31 -0
  107. package/lib/TableEx.d.ts +65 -0
  108. package/lib/TableEx.js +270 -0
  109. package/lib/TextFieldEx.d.ts +101 -0
  110. package/lib/TextFieldEx.js +126 -0
  111. package/lib/Tiplist.d.ts +18 -0
  112. package/lib/Tiplist.js +157 -0
  113. package/lib/TooltipClick.d.ts +15 -0
  114. package/lib/TooltipClick.js +40 -0
  115. package/lib/UserAvatar.d.ts +24 -0
  116. package/lib/UserAvatar.js +25 -0
  117. package/lib/UserAvatarEditor.d.ts +53 -0
  118. package/lib/UserAvatarEditor.js +129 -0
  119. package/lib/app/CommonApp.d.ts +38 -0
  120. package/lib/app/CommonApp.js +149 -0
  121. package/lib/app/IServiceAppSettings.d.ts +11 -0
  122. package/lib/app/IServiceAppSettings.js +1 -0
  123. package/lib/app/IServicePage.d.ts +6 -0
  124. package/lib/app/IServicePage.js +1 -0
  125. package/lib/app/IServiceUser.d.ts +14 -0
  126. package/lib/app/IServiceUser.js +1 -0
  127. package/lib/app/ISmartERPUser.d.ts +14 -0
  128. package/lib/app/ISmartERPUser.js +1 -0
  129. package/lib/app/Labels.d.ts +65 -0
  130. package/lib/app/Labels.js +62 -0
  131. package/lib/app/ReactApp.d.ts +195 -0
  132. package/lib/app/ReactApp.js +296 -0
  133. package/lib/app/ServiceApp.d.ts +78 -0
  134. package/lib/app/ServiceApp.js +244 -0
  135. package/lib/index.d.ts +74 -0
  136. package/lib/index.js +74 -0
  137. package/lib/pages/CommonPage.d.ts +11 -0
  138. package/lib/pages/CommonPage.js +60 -0
  139. package/lib/pages/CommonPageProps.d.ts +59 -0
  140. package/lib/pages/CommonPageProps.js +1 -0
  141. package/lib/pages/DataGridPage.d.ts +9 -0
  142. package/lib/pages/DataGridPage.js +79 -0
  143. package/lib/pages/DataGridPageProps.d.ts +17 -0
  144. package/lib/pages/DataGridPageProps.js +1 -0
  145. package/lib/pages/EditPage.d.ts +33 -0
  146. package/lib/pages/EditPage.js +29 -0
  147. package/lib/pages/FixedListPage.d.ts +15 -0
  148. package/lib/pages/FixedListPage.js +70 -0
  149. package/lib/pages/ListPage.d.ts +9 -0
  150. package/lib/pages/ListPage.js +50 -0
  151. package/lib/pages/ListPageProps.d.ts +7 -0
  152. package/lib/pages/ListPageProps.js +1 -0
  153. package/lib/pages/ResponsivePage.d.ts +9 -0
  154. package/lib/pages/ResponsivePage.js +45 -0
  155. package/lib/pages/ResponsivePageProps.d.ts +39 -0
  156. package/lib/pages/ResponsivePageProps.js +1 -0
  157. package/lib/pages/SearchPageProps.d.ts +30 -0
  158. package/lib/pages/SearchPageProps.js +1 -0
  159. package/lib/pages/TablePage.d.ts +9 -0
  160. package/lib/pages/TablePage.js +69 -0
  161. package/lib/pages/TablePageProps.d.ts +7 -0
  162. package/lib/pages/TablePageProps.js +1 -0
  163. package/lib/pages/ViewPage.d.ts +66 -0
  164. package/lib/pages/ViewPage.js +105 -0
  165. package/lib/texts/DateText.d.ts +34 -0
  166. package/lib/texts/DateText.js +25 -0
  167. package/lib/texts/MoneyText.d.ts +21 -0
  168. package/lib/texts/MoneyText.js +14 -0
  169. package/lib/texts/NumberText.d.ts +25 -0
  170. package/lib/texts/NumberText.js +14 -0
  171. package/package.json +97 -0
  172. package/src/AuditDisplay.tsx +114 -0
  173. package/src/AutocompleteExtendedProps.ts +83 -0
  174. package/src/BackButton.tsx +55 -0
  175. package/src/BridgeCloseButton.tsx +69 -0
  176. package/src/ButtonLink.tsx +32 -0
  177. package/src/ComboBox.tsx +251 -0
  178. package/src/CountdownButton.tsx +119 -0
  179. package/src/CustomFabProps.ts +32 -0
  180. package/src/DataGridEx.tsx +713 -0
  181. package/src/DataGridRenderers.tsx +140 -0
  182. package/src/DialogButton.tsx +163 -0
  183. package/src/DnDList.tsx +344 -0
  184. package/src/DraggablePaperComponent.tsx +19 -0
  185. package/src/EmailInput.tsx +24 -0
  186. package/src/FabBox.tsx +51 -0
  187. package/src/FlexBox.tsx +20 -0
  188. package/src/GridDataFormat.tsx +77 -0
  189. package/src/IconButtonLink.tsx +29 -0
  190. package/src/InputField.tsx +82 -0
  191. package/src/ItemList.tsx +204 -0
  192. package/src/ListItemRightIcon.tsx +9 -0
  193. package/src/ListMoreDisplay.tsx +205 -0
  194. package/src/LoadingButton.tsx +75 -0
  195. package/src/MUGlobal.ts +220 -0
  196. package/src/MaskInput.tsx +107 -0
  197. package/src/MobileListItemRenderer.tsx +79 -0
  198. package/src/MoreFab.tsx +211 -0
  199. package/src/NotifierMU.tsx +654 -0
  200. package/src/NotifierPromptProps.ts +24 -0
  201. package/src/OptionGroup.tsx +223 -0
  202. package/src/PList.tsx +27 -0
  203. package/src/ProgressCount.tsx +166 -0
  204. package/src/PullToRefreshUI.tsx +21 -0
  205. package/src/RLink.tsx +64 -0
  206. package/src/ResponsibleContainer.tsx +394 -0
  207. package/src/ScrollTopFab.tsx +34 -0
  208. package/src/ScrollerListEx.tsx +387 -0
  209. package/src/SearchBar.tsx +396 -0
  210. package/src/SearchField.tsx +82 -0
  211. package/src/SearchOptionGroup.tsx +31 -0
  212. package/src/SelectBool.tsx +33 -0
  213. package/src/SelectEx.tsx +290 -0
  214. package/src/ShowDataComparison.tsx +106 -0
  215. package/src/Switch.tsx +94 -0
  216. package/src/SwitchAnt.tsx +95 -0
  217. package/src/TabBox.tsx +118 -0
  218. package/src/TableEx.tsx +558 -0
  219. package/src/TextFieldEx.tsx +249 -0
  220. package/src/Tiplist.tsx +303 -0
  221. package/src/TooltipClick.tsx +84 -0
  222. package/src/UserAvatar.tsx +64 -0
  223. package/src/UserAvatarEditor.tsx +287 -0
  224. package/src/app/CommonApp.ts +223 -0
  225. package/src/app/IServiceAppSettings.ts +13 -0
  226. package/src/app/IServicePage.ts +6 -0
  227. package/src/app/IServiceUser.ts +17 -0
  228. package/src/app/ISmartERPUser.ts +16 -0
  229. package/src/app/Labels.ts +77 -0
  230. package/src/app/ReactApp.ts +504 -0
  231. package/src/app/ServiceApp.ts +352 -0
  232. package/src/index.ts +77 -0
  233. package/src/pages/CommonPage.tsx +128 -0
  234. package/src/pages/CommonPageProps.ts +70 -0
  235. package/src/pages/DataGridPage.tsx +140 -0
  236. package/src/pages/DataGridPageProps.ts +24 -0
  237. package/src/pages/EditPage.tsx +114 -0
  238. package/src/pages/FixedListPage.tsx +141 -0
  239. package/src/pages/ListPage.tsx +90 -0
  240. package/src/pages/ListPageProps.ts +12 -0
  241. package/src/pages/ResponsivePage.tsx +68 -0
  242. package/src/pages/ResponsivePageProps.ts +57 -0
  243. package/src/pages/SearchPageProps.ts +39 -0
  244. package/src/pages/TablePage.tsx +126 -0
  245. package/src/pages/TablePageProps.ts +12 -0
  246. package/src/pages/ViewPage.tsx +282 -0
  247. package/src/texts/DateText.tsx +74 -0
  248. package/src/texts/MoneyText.tsx +49 -0
  249. package/src/texts/NumberText.tsx +40 -0
  250. package/tsconfig.json +19 -0
@@ -0,0 +1,140 @@
1
+ import {
2
+ GridDataGet,
3
+ GridLoadDataProps,
4
+ ScrollerGridForwardRef,
5
+ useCombinedRefs,
6
+ useDimensions
7
+ } from '@etsoo/react';
8
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
9
+ import { Box, Stack } from '@mui/material';
10
+ import React from 'react';
11
+ import { DataGridEx } from '../DataGridEx';
12
+ import { MUGlobal } from '../MUGlobal';
13
+ import { SearchBar } from '../SearchBar';
14
+ import { CommonPage } from './CommonPage';
15
+ import { DataGridPageProps } from './DataGridPageProps';
16
+
17
+ interface LocalStates<T> {
18
+ data?: FormData;
19
+ element?: HTMLElement;
20
+ height?: number;
21
+ ref?: ScrollerGridForwardRef<T>;
22
+ }
23
+
24
+ /**
25
+ * DataGrid page
26
+ * @param props Props
27
+ * @returns Component
28
+ */
29
+ export function DataGridPage<
30
+ T extends object,
31
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
32
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
33
+ >(props: DataGridPageProps<T, F, D>) {
34
+ // Destruct
35
+ const {
36
+ adjustHeight,
37
+ fields,
38
+ fieldTemplate,
39
+ height,
40
+ loadData,
41
+ mRef,
42
+ sizeReadyMiliseconds = 100,
43
+ pageProps = {},
44
+ ...rest
45
+ } = props;
46
+
47
+ pageProps.paddings ??= MUGlobal.pagePaddings;
48
+
49
+ // States
50
+ const [states, setStates] = React.useReducer(
51
+ (currentState: LocalStates<T>, newState: Partial<LocalStates<T>>) => {
52
+ return { ...currentState, ...newState };
53
+ },
54
+ {
55
+ height
56
+ }
57
+ );
58
+
59
+ const refs = useCombinedRefs<ScrollerGridForwardRef<T>>(
60
+ mRef,
61
+ (ref: ScrollerGridForwardRef<T> | null | undefined) => {
62
+ if (ref == null) return;
63
+ states.ref = ref;
64
+ //setStates({ ref });
65
+ }
66
+ );
67
+
68
+ // On submit callback
69
+ const onSubmit = (data: FormData, _reset: boolean) => {
70
+ setStates({ data });
71
+ };
72
+
73
+ const localLoadData = (props: GridLoadDataProps) => {
74
+ const data = GridDataGet(props, fieldTemplate);
75
+ return loadData(data);
76
+ };
77
+
78
+ // Watch container
79
+ const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
80
+ const rect = dimensions[0][2];
81
+
82
+ React.useEffect(() => {
83
+ if (rect != null && rect.height > 50 && height == null) {
84
+ let gridHeight =
85
+ document.documentElement.clientHeight -
86
+ Math.round(rect.top + rect.height + 1);
87
+
88
+ const style = window.getComputedStyle(dimensions[0][1]!);
89
+ const paddingBottom = parseFloat(style.paddingBottom);
90
+ if (!isNaN(paddingBottom)) gridHeight -= paddingBottom;
91
+
92
+ if (adjustHeight != null) {
93
+ gridHeight -= adjustHeight(gridHeight);
94
+ }
95
+
96
+ if (gridHeight !== states.height) setStates({ height: gridHeight });
97
+ }
98
+ }, [rect]);
99
+
100
+ const list = React.useMemo(() => {
101
+ const gridHeight = states.height;
102
+ if (gridHeight == null) return;
103
+
104
+ return (
105
+ <DataGridEx<T, D>
106
+ autoLoad={false}
107
+ height={gridHeight}
108
+ loadData={localLoadData}
109
+ mRef={refs}
110
+ outerRef={(element?: HTMLDivElement) => {
111
+ if (element != null) setStates({ element });
112
+ }}
113
+ {...rest}
114
+ />
115
+ );
116
+ }, [states.height]);
117
+
118
+ const { ref, data } = states;
119
+ React.useEffect(() => {
120
+ if (ref == null || data == null) return;
121
+ ref.reset({ data });
122
+ }, [ref, data]);
123
+
124
+ // Layout
125
+ return (
126
+ <CommonPage {...pageProps} scrollContainer={states.element}>
127
+ <Stack>
128
+ <Box
129
+ ref={dimensions[0][0]}
130
+ sx={{
131
+ paddingBottom: pageProps.paddings
132
+ }}
133
+ >
134
+ <SearchBar fields={fields} onSubmit={onSubmit} />
135
+ </Box>
136
+ {list}
137
+ </Stack>
138
+ </CommonPage>
139
+ );
140
+ }
@@ -0,0 +1,24 @@
1
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
2
+ import { DataGridExProps } from '../DataGridEx';
3
+ import { SearchPageProps } from './SearchPageProps';
4
+
5
+ /**
6
+ * DataGrid page props
7
+ */
8
+ export type DataGridPageProps<
9
+ T extends object,
10
+ F extends DataTypes.BasicTemplate,
11
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
12
+ > = SearchPageProps<T, F> &
13
+ Omit<DataGridExProps<T, D>, 'loadData' | 'height'> & {
14
+ /**
15
+ * Height will be deducted
16
+ * @param height Current calcuated height
17
+ */
18
+ adjustHeight?: (height: number) => number;
19
+
20
+ /**
21
+ * Grid height
22
+ */
23
+ height?: number;
24
+ };
@@ -0,0 +1,114 @@
1
+ import { Button, Grid } from '@mui/material';
2
+ import React, { FormEventHandler } from 'react';
3
+ import { MUGlobal } from '../MUGlobal';
4
+ import { CommonPage, CommonPageScrollContainer } from './CommonPage';
5
+ import { CommonPageProps } from './CommonPageProps';
6
+ import SaveIcon from '@mui/icons-material/Save';
7
+ import DeleteIcon from '@mui/icons-material/Delete';
8
+ import { BackButton } from '../BackButton';
9
+ import { Labels } from '../app/Labels';
10
+
11
+ /**
12
+ * Add / Edit page props
13
+ */
14
+ export interface EditPageProps extends Omit<CommonPageProps, 'onSubmit'> {
15
+ /**
16
+ * Is editing
17
+ */
18
+ isEditing?: boolean;
19
+
20
+ /**
21
+ * On form submit
22
+ */
23
+ onSubmit?: FormEventHandler<HTMLFormElement>;
24
+
25
+ /**
26
+ * On delete callback
27
+ */
28
+ onDelete?: () => Promise<void> | void;
29
+
30
+ /**
31
+ * Submit button disabled or not
32
+ */
33
+ submitDisabled?: boolean;
34
+
35
+ /**
36
+ * Support back click
37
+ * @default true
38
+ */
39
+ supportBack?: boolean;
40
+ }
41
+
42
+ /**
43
+ * Add / Edit page
44
+ * @param props Props
45
+ */
46
+ export function EditPage(props: EditPageProps) {
47
+ // Destruct
48
+ const {
49
+ children,
50
+ isEditing,
51
+ onDelete,
52
+ onSubmit,
53
+ paddings = MUGlobal.pagePaddings,
54
+ scrollContainer = CommonPageScrollContainer,
55
+ supportBack = true,
56
+ submitDisabled = false,
57
+ ...rest
58
+ } = props;
59
+
60
+ // Labels
61
+ const labels = Labels.CommonPage;
62
+
63
+ return (
64
+ <CommonPage
65
+ paddings={paddings}
66
+ scrollContainer={scrollContainer}
67
+ {...rest}
68
+ >
69
+ <form onSubmit={onSubmit}>
70
+ <Grid
71
+ container
72
+ justifyContent="left"
73
+ spacing={paddings}
74
+ paddingTop={1}
75
+ >
76
+ {children}
77
+ </Grid>
78
+ <Grid
79
+ container
80
+ position="sticky"
81
+ display="flex"
82
+ gap={paddings}
83
+ sx={{
84
+ top: 'auto',
85
+ bottom: (theme) =>
86
+ MUGlobal.updateWithTheme(paddings, theme.spacing),
87
+ paddingTop: paddings
88
+ }}
89
+ >
90
+ {isEditing && onDelete && (
91
+ <Button
92
+ color="primary"
93
+ variant="outlined"
94
+ onClick={() => onDelete()}
95
+ startIcon={<DeleteIcon color="warning" />}
96
+ >
97
+ {labels.delete}
98
+ </Button>
99
+ )}
100
+ <Button
101
+ variant="contained"
102
+ type="submit"
103
+ startIcon={<SaveIcon />}
104
+ sx={{ flexGrow: 1 }}
105
+ disabled={submitDisabled}
106
+ >
107
+ {labels.save}
108
+ </Button>
109
+ {supportBack && <BackButton title={labels.back} />}
110
+ </Grid>
111
+ </form>
112
+ </CommonPage>
113
+ );
114
+ }
@@ -0,0 +1,141 @@
1
+ import {
2
+ GridDataGet,
3
+ GridLoadDataProps,
4
+ ScrollerListForwardRef,
5
+ useCombinedRefs,
6
+ useDimensions
7
+ } from '@etsoo/react';
8
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
9
+ import { Box, Stack } from '@mui/material';
10
+ import React from 'react';
11
+ import { MUGlobal } from '../MUGlobal';
12
+ import { ScrollerListEx } from '../ScrollerListEx';
13
+ import { SearchBar } from '../SearchBar';
14
+ import { CommonPage } from './CommonPage';
15
+ import { ListPageProps } from './ListPageProps';
16
+
17
+ /**
18
+ * Fixed height list page
19
+ * @param props Props
20
+ * @returns Component
21
+ */
22
+ export function FixedListPage<
23
+ T extends object,
24
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
25
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
26
+ >(
27
+ props: ListPageProps<T, F, D> & {
28
+ /**
29
+ * Height will be deducted
30
+ * @param height Current calcuated height
31
+ */
32
+ adjustHeight?: (height: number) => number;
33
+ }
34
+ ) {
35
+ // Destruct
36
+ const {
37
+ adjustHeight,
38
+ fields,
39
+ fieldTemplate,
40
+ loadData,
41
+ mRef,
42
+ sizeReadyMiliseconds = 0,
43
+ pageProps = {},
44
+ ...rest
45
+ } = props;
46
+
47
+ pageProps.paddings ??= MUGlobal.pagePaddings;
48
+
49
+ // States
50
+ const [states] = React.useState<{
51
+ data?: FormData;
52
+ ref?: ScrollerListForwardRef<T>;
53
+ }>({});
54
+
55
+ // Scroll container
56
+ const [scrollContainer, updateScrollContainer] = React.useState<
57
+ HTMLElement | undefined
58
+ >();
59
+
60
+ const refs = useCombinedRefs(
61
+ mRef,
62
+ (ref: ScrollerListForwardRef<T> | null | undefined) => {
63
+ if (ref == null) return;
64
+
65
+ const first = states.ref == null;
66
+
67
+ states.ref = ref;
68
+
69
+ if (first) reset();
70
+ }
71
+ );
72
+
73
+ const reset = () => {
74
+ if (states.data == null || states.ref == null) return;
75
+ states.ref.reset({ data: states.data });
76
+ };
77
+
78
+ // On submit callback
79
+ const onSubmit = (data: FormData, _reset: boolean) => {
80
+ states.data = data;
81
+ reset();
82
+ };
83
+
84
+ const localLoadData = (props: GridLoadDataProps) => {
85
+ const data = GridDataGet(props, fieldTemplate);
86
+ return loadData(data);
87
+ };
88
+
89
+ // Watch container
90
+ const { dimensions } = useDimensions(1, undefined, sizeReadyMiliseconds);
91
+ const rect = dimensions[0][2];
92
+ const list = React.useMemo(() => {
93
+ if (rect != null && rect.height > 50) {
94
+ let height =
95
+ document.documentElement.clientHeight -
96
+ Math.round(rect.top + rect.height + 1);
97
+
98
+ if (adjustHeight != null) {
99
+ height -= adjustHeight(height);
100
+ }
101
+
102
+ return (
103
+ <Box
104
+ id="list-container"
105
+ sx={{
106
+ height: height + 'px'
107
+ }}
108
+ >
109
+ <ScrollerListEx<T, D>
110
+ autoLoad={false}
111
+ height={height}
112
+ loadData={localLoadData}
113
+ mRef={refs}
114
+ oRef={(element) => {
115
+ if (element != null) updateScrollContainer(element);
116
+ }}
117
+ {...rest}
118
+ />
119
+ </Box>
120
+ );
121
+ }
122
+ }, [rect]);
123
+
124
+ const { paddings, ...pageRest } = pageProps;
125
+
126
+ // Layout
127
+ return (
128
+ <CommonPage
129
+ {...pageRest}
130
+ paddings={{}}
131
+ scrollContainer={scrollContainer}
132
+ >
133
+ <Stack>
134
+ <Box ref={dimensions[0][0]} sx={{ padding: paddings }}>
135
+ <SearchBar fields={fields} onSubmit={onSubmit} />
136
+ </Box>
137
+ {list}
138
+ </Stack>
139
+ </CommonPage>
140
+ );
141
+ }
@@ -0,0 +1,90 @@
1
+ import {
2
+ GridDataGet,
3
+ GridLoadDataProps,
4
+ ScrollerListForwardRef,
5
+ useCombinedRefs
6
+ } from '@etsoo/react';
7
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
8
+ import { Box, Stack } from '@mui/material';
9
+ import React from 'react';
10
+ import { MUGlobal } from '../MUGlobal';
11
+ import { ScrollerListEx } from '../ScrollerListEx';
12
+ import { SearchBar } from '../SearchBar';
13
+ import { CommonPage, CommonPageScrollContainer } from './CommonPage';
14
+ import { ListPageProps } from './ListPageProps';
15
+
16
+ /**
17
+ * List page
18
+ * @param props Props
19
+ * @returns Component
20
+ */
21
+ export function ListPage<
22
+ T extends object,
23
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
24
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
25
+ >(props: ListPageProps<T, F, D>) {
26
+ // Destruct
27
+ const {
28
+ fields,
29
+ fieldTemplate,
30
+ loadData,
31
+ mRef,
32
+ pageProps = {},
33
+ ...rest
34
+ } = props;
35
+
36
+ pageProps.paddings ??= MUGlobal.pagePaddings;
37
+
38
+ // States
39
+ const [states] = React.useState<{
40
+ data?: FormData;
41
+ ref?: ScrollerListForwardRef<T>;
42
+ }>({});
43
+
44
+ const refs = useCombinedRefs(mRef, (ref: ScrollerListForwardRef<T>) => {
45
+ if (ref == null) return;
46
+
47
+ const first = states.ref == null;
48
+
49
+ states.ref = ref;
50
+
51
+ if (first) reset();
52
+ });
53
+
54
+ const reset = () => {
55
+ if (states.data == null || states.ref == null) return;
56
+ states.ref.reset({ data: states.data });
57
+ };
58
+
59
+ // On submit callback
60
+ const onSubmit = (data: FormData, _reset: boolean) => {
61
+ states.data = data;
62
+ reset();
63
+ };
64
+
65
+ const localLoadData = (props: GridLoadDataProps) => {
66
+ const data = GridDataGet(props, fieldTemplate);
67
+ return loadData(data);
68
+ };
69
+
70
+ // Layout
71
+ return (
72
+ <CommonPage {...pageProps} scrollContainer={CommonPageScrollContainer}>
73
+ <Stack>
74
+ <Box
75
+ sx={{
76
+ paddingBottom: pageProps.paddings
77
+ }}
78
+ >
79
+ <SearchBar fields={fields} onSubmit={onSubmit} />
80
+ </Box>
81
+ <ScrollerListEx<T, D>
82
+ autoLoad={false}
83
+ loadData={localLoadData}
84
+ mRef={refs}
85
+ {...rest}
86
+ />
87
+ </Stack>
88
+ </CommonPage>
89
+ );
90
+ }
@@ -0,0 +1,12 @@
1
+ import { DataTypes } from '@etsoo/shared';
2
+ import { ScrollerListExProps } from '../ScrollerListEx';
3
+ import { SearchPageProps } from './SearchPageProps';
4
+
5
+ /**
6
+ * List page props
7
+ */
8
+ export type ListPageProps<
9
+ T extends object,
10
+ F extends DataTypes.BasicTemplate,
11
+ D extends DataTypes.Keys<T>
12
+ > = SearchPageProps<T, F> & Omit<ScrollerListExProps<T, D>, 'loadData'>;
@@ -0,0 +1,68 @@
1
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
2
+ import React from 'react';
3
+ import { MUGlobal } from '../MUGlobal';
4
+ import { ResponsibleContainer } from '../ResponsibleContainer';
5
+ import { CommonPage } from './CommonPage';
6
+ import { ResponsePageProps } from './ResponsivePageProps';
7
+
8
+ /**
9
+ * Fixed height list page
10
+ * @param props Props
11
+ * @returns Component
12
+ */
13
+ export function ResponsivePage<
14
+ T extends object,
15
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
16
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
17
+ >(props: ResponsePageProps<T, F, D>) {
18
+ // Destruct
19
+ const { pageProps = {}, ...rest } = props;
20
+
21
+ pageProps.paddings ??= MUGlobal.pagePaddings;
22
+ const { paddings, fabColumnDirection, ...pageRest } = pageProps;
23
+
24
+ // State
25
+ const [scrollContainer, setScrollContainer] = React.useState<HTMLElement>();
26
+ const [direction, setDirection] = React.useState(fabColumnDirection);
27
+
28
+ // Layout
29
+ return (
30
+ <CommonPage
31
+ {...pageRest}
32
+ paddings={{}}
33
+ scrollContainer={scrollContainer}
34
+ fabColumnDirection={direction}
35
+ >
36
+ <ResponsibleContainer<T, F, D>
37
+ paddings={paddings}
38
+ containerBoxSx={(paddings, hasField, _dataGrid) => {
39
+ // Half
40
+ const half = MUGlobal.half(paddings);
41
+
42
+ // .SearchBox keep the same to avoid flick when switching between DataGrid and List
43
+ return {
44
+ paddingTop: paddings,
45
+ '& .SearchBox': {
46
+ marginLeft: paddings,
47
+ marginRight: paddings,
48
+ marginBottom: hasField ? half : 0
49
+ },
50
+ '& .ListBox': {
51
+ marginBottom: paddings
52
+ },
53
+ '& .DataGridBox': {
54
+ marginLeft: paddings,
55
+ marginRight: paddings,
56
+ marginBottom: paddings
57
+ }
58
+ };
59
+ }}
60
+ elementReady={(element, isDataGrid) => {
61
+ setDirection(!isDataGrid);
62
+ setScrollContainer(element);
63
+ }}
64
+ {...rest}
65
+ />
66
+ </CommonPage>
67
+ );
68
+ }
@@ -0,0 +1,57 @@
1
+ import { GridMethodRef } from '@etsoo/react';
2
+ import { DataTypes, IdDefaultType } from '@etsoo/shared';
3
+ import { ListChildComponentProps } from 'react-window';
4
+ import {
5
+ ScrollerListExInnerItemRendererProps,
6
+ ScrollerListExItemSize
7
+ } from '../ScrollerListEx';
8
+ import { DataGridPageProps } from './DataGridPageProps';
9
+
10
+ /**
11
+ * Response page props
12
+ */
13
+ export type ResponsePageProps<
14
+ T extends object,
15
+ F extends DataTypes.BasicTemplate,
16
+ D extends DataTypes.Keys<T> = IdDefaultType<T>
17
+ > = Omit<
18
+ DataGridPageProps<T, F, D>,
19
+ 'mRef' | 'itemKey' | 'onScroll' | 'onItemsRendered'
20
+ > & {
21
+ /**
22
+ * Min width to show Datagrid
23
+ */
24
+ dataGridMinWidth?: number;
25
+
26
+ /**
27
+ * Inner item renderer
28
+ */
29
+ innerItemRenderer: (
30
+ props: ScrollerListExInnerItemRendererProps<T>
31
+ ) => React.ReactNode;
32
+
33
+ /**
34
+ * Item renderer
35
+ */
36
+ itemRenderer?: (props: ListChildComponentProps<T>) => React.ReactElement;
37
+
38
+ /**
39
+ * Item size, a function indicates its a variable size list
40
+ */
41
+ itemSize: ScrollerListExItemSize;
42
+
43
+ /**
44
+ * Methods
45
+ */
46
+ mRef?: React.MutableRefObject<GridMethodRef<T> | undefined>;
47
+
48
+ /**
49
+ * Pull to refresh data
50
+ */
51
+ pullToRefresh?: boolean;
52
+
53
+ /**
54
+ * Quick action for double click or click under mobile
55
+ */
56
+ quickAction?: (data: T) => void;
57
+ };
@@ -0,0 +1,39 @@
1
+ import { GridJsonData, GridLoader } from '@etsoo/react';
2
+ import { DataTypes } from '@etsoo/shared';
3
+ import { CommonPageProps } from './CommonPageProps';
4
+
5
+ /**
6
+ * Search page props
7
+ */
8
+ export type SearchPageProps<
9
+ T extends object,
10
+ F extends DataTypes.BasicTemplate
11
+ > = Omit<GridLoader<T>, 'loadData'> & {
12
+ /**
13
+ * Search fields
14
+ */
15
+ fields: React.ReactElement[];
16
+
17
+ /**
18
+ * Search field template
19
+ */
20
+ fieldTemplate?: F;
21
+
22
+ /**
23
+ * Load data callback
24
+ */
25
+ loadData: (
26
+ data: GridJsonData & DataTypes.BasicTemplateType<F>
27
+ ) => PromiseLike<T[] | null | undefined>;
28
+
29
+ /**
30
+ * Page props
31
+ */
32
+ pageProps?: CommonPageProps;
33
+
34
+ /**
35
+ * Size ready to read miliseconds span
36
+ * @default 100
37
+ */
38
+ sizeReadyMiliseconds?: number;
39
+ };