@etsoo/react 1.5.31 → 1.5.34

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 (43) hide show
  1. package/lib/app/ReactApp.d.ts +3 -3
  2. package/lib/app/ReactApp.js +9 -7
  3. package/lib/app/ReactUtils.d.ts +0 -25
  4. package/lib/app/ReactUtils.js +0 -91
  5. package/lib/components/GridColumn.d.ts +1 -1
  6. package/lib/index.d.ts +0 -1
  7. package/lib/index.js +0 -1
  8. package/lib/mu/BackButton.js +4 -3
  9. package/lib/mu/ButtonLink.js +2 -2
  10. package/lib/mu/FabBox.js +9 -7
  11. package/lib/mu/IconButtonLink.js +2 -2
  12. package/lib/mu/MoreFab.js +1 -1
  13. package/lib/mu/NotifierMU.d.ts +1 -1
  14. package/lib/mu/RLink.d.ts +2 -2
  15. package/lib/mu/RLink.js +1 -1
  16. package/lib/mu/TabBox.js +1 -1
  17. package/lib/mu/pages/CommonPage.js +1 -5
  18. package/lib/notifier/Notifier.d.ts +1 -1
  19. package/lib/states/CultureState.d.ts +2 -2
  20. package/lib/states/IState.d.ts +1 -5
  21. package/lib/states/PageState.d.ts +2 -2
  22. package/lib/states/State.d.ts +1 -1
  23. package/lib/states/UserState.d.ts +2 -2
  24. package/package.json +3 -4
  25. package/src/app/ReactApp.ts +11 -10
  26. package/src/app/ReactUtils.ts +0 -112
  27. package/src/index.ts +0 -1
  28. package/src/mu/BackButton.tsx +5 -3
  29. package/src/mu/ButtonLink.tsx +2 -3
  30. package/src/mu/FabBox.tsx +9 -7
  31. package/src/mu/IconButtonLink.tsx +2 -2
  32. package/src/mu/MoreFab.tsx +1 -1
  33. package/src/mu/RLink.tsx +2 -2
  34. package/src/mu/TabBox.tsx +1 -1
  35. package/src/mu/pages/CommonPage.tsx +1 -6
  36. package/src/states/CultureState.ts +2 -2
  37. package/src/states/IState.ts +0 -5
  38. package/src/states/PageState.ts +2 -2
  39. package/src/states/State.tsx +3 -1
  40. package/src/states/UserState.ts +2 -2
  41. package/lib/states/RouterProps.d.ts +0 -39
  42. package/lib/states/RouterProps.js +0 -14
  43. package/src/states/RouterProps.ts +0 -46
@@ -1,7 +1,6 @@
1
1
  import { CoreApp, IActionResult, IAppSettings, ICoreApp, IUser, IUserData } from '@etsoo/appscript';
2
2
  import { NotificationRenderProps, NotificationReturn } from '@etsoo/notificationbase';
3
3
  import { DataTypes } from '@etsoo/shared';
4
- import { History } from '@reach/router';
5
4
  import React from 'react';
6
5
  import { NotificationReactCallProps } from '../notifier/Notifier';
7
6
  import { CultureAction, CultureState } from '../states/CultureState';
@@ -9,6 +8,7 @@ import { IStateProps } from '../states/IState';
9
8
  import { IPageData, PageAction, PageState } from '../states/PageState';
10
9
  import { UserAction, UserState } from '../states/UserState';
11
10
  import { InputDialogProps } from './InputDialogProps';
11
+ import { History } from 'history';
12
12
  /**
13
13
  * Global application
14
14
  */
@@ -36,7 +36,7 @@ export interface IReactApp<S extends IAppSettings, D extends IUser, P extends IP
36
36
  /**
37
37
  * Router history
38
38
  */
39
- readonly history?: History;
39
+ readonly history: History;
40
40
  /**
41
41
  * Is screen size down 'sm'
42
42
  */
@@ -79,7 +79,7 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
79
79
  /**
80
80
  * Router history
81
81
  */
82
- readonly history?: History;
82
+ readonly history: History;
83
83
  /**
84
84
  * Page state
85
85
  */
@@ -8,7 +8,7 @@ import { CultureState } from '../states/CultureState';
8
8
  import { PageActionType, PageState } from '../states/PageState';
9
9
  import { UserActionType, UserState } from '../states/UserState';
10
10
  import { Labels } from './Labels';
11
- import { ReactUtils } from './ReactUtils';
11
+ import { createBrowserHistory, createMemoryHistory } from 'history';
12
12
  /**
13
13
  * Global application
14
14
  */
@@ -65,15 +65,18 @@ export class ReactApp extends CoreApp {
65
65
  * User state
66
66
  */
67
67
  this.userState = new UserState();
68
- this.history =
69
- BridgeUtils.host == null
70
- ? undefined
71
- : ReactUtils.getMemoryHistory(BridgeUtils.host.getStartUrl());
72
68
  if (BridgeUtils.host) {
69
+ const startUrl = BridgeUtils.host.getStartUrl();
70
+ this.history = createMemoryHistory({
71
+ initialEntries: startUrl == null ? undefined : [startUrl]
72
+ });
73
73
  BridgeUtils.host.onUpdate((app, version) => {
74
74
  this.notifier.message(NotificationMessageType.Success, this.get('updateTip') + `(${[app, version].join(', ')})`, this.get('updateReady'));
75
75
  });
76
76
  }
77
+ else {
78
+ this.history = createBrowserHistory();
79
+ }
77
80
  this.cultureState = new CultureState(settings.currentCulture);
78
81
  this.pageState = new PageState();
79
82
  globalApp = this;
@@ -204,8 +207,7 @@ export class ReactApp extends CoreApp {
204
207
  * @param url Url
205
208
  */
206
209
  redirectTo(url) {
207
- const navigate = ReactUtils.getNavigateFn();
208
- navigate(url);
210
+ this.history.push(url);
209
211
  }
210
212
  /**
211
213
  * Set page data
@@ -1,38 +1,14 @@
1
- import { History, HistorySource } from '@reach/router';
2
1
  import React from 'react';
3
- declare type MemoryHistorySource = HistorySource & {
4
- history: {
5
- get entries(): any;
6
- get index(): number;
7
- go(to: number): void;
8
- };
9
- };
10
2
  /**
11
3
  * React utils
12
4
  */
13
5
  export declare namespace ReactUtils {
14
- /**
15
- * Cretae memory source to fix go back bug
16
- * @param initialPath Initial path
17
- */
18
- function createMemorySource(initialPath?: string): MemoryHistorySource;
19
6
  /**
20
7
  * Format input value
21
8
  * @param value Input value
22
9
  * @returns Formatted value
23
10
  */
24
11
  function formatInputValue(value: unknown): string | number | any[] | undefined;
25
- /**
26
- * Get memory history
27
- * @param initialPath Initial path
28
- * @returns History
29
- */
30
- function getMemoryHistory(initialPath?: string | null): History;
31
- /**
32
- * Get navigate function, works with memory history
33
- * @returns NavigateFn
34
- */
35
- function getNavigateFn(): import("@reach/router").NavigateFn;
36
12
  /**
37
13
  * Is safe click
38
14
  * @param event Mouse event
@@ -47,4 +23,3 @@ export declare namespace ReactUtils {
47
23
  */
48
24
  function triggerChange(input: HTMLInputElement, value: string, cancelable: boolean): void;
49
25
  }
50
- export {};
@@ -1,77 +1,8 @@
1
- import { createHistory, navigate } from '@reach/router';
2
1
  /**
3
2
  * React utils
4
3
  */
5
4
  export var ReactUtils;
6
5
  (function (ReactUtils) {
7
- // Memory history
8
- // https://github.com/reach/router/issues/225
9
- let memoryHistory;
10
- /**
11
- * Cretae memory source to fix go back bug
12
- * @param initialPath Initial path
13
- */
14
- function createMemorySource(initialPath = '/') {
15
- const searchIndex = initialPath.indexOf('?');
16
- const pathname = searchIndex > -1
17
- ? initialPath.substring(0, searchIndex)
18
- : initialPath;
19
- const initialLocation = {
20
- pathname,
21
- search: searchIndex > -1 ? initialPath.substring(searchIndex) : ''
22
- };
23
- let index = 0;
24
- const stack = [initialLocation];
25
- const states = [null];
26
- return {
27
- get location() {
28
- return stack[index];
29
- },
30
- addEventListener(name, fn) { },
31
- removeEventListener(name, fn) { },
32
- history: {
33
- get entries() {
34
- return stack;
35
- },
36
- get index() {
37
- return index;
38
- },
39
- get state() {
40
- return states[index];
41
- },
42
- pushState(state, _, uri) {
43
- const [pathname, search = ''] = uri.split('?');
44
- index++;
45
- // View a, index = 0
46
- // View b, index = 1
47
- // Go(-1), a, index = 0
48
- // View c, index = 1, directly push is wrong
49
- if (index < stack.length) {
50
- stack.splice(index);
51
- states.splice(index);
52
- }
53
- stack.push({
54
- pathname,
55
- search: search.length ? `?${search}` : search
56
- });
57
- states.push(state);
58
- },
59
- replaceState(state, _, uri) {
60
- const [pathname, search = ''] = uri.split('?');
61
- stack[index] = { pathname, search };
62
- states[index] = state;
63
- },
64
- go(to) {
65
- const newIndex = index + to;
66
- if (newIndex < 0 || newIndex > states.length - 1) {
67
- return;
68
- }
69
- index = newIndex;
70
- }
71
- }
72
- };
73
- }
74
- ReactUtils.createMemorySource = createMemorySource;
75
6
  /**
76
7
  * Format input value
77
8
  * @param value Input value
@@ -89,28 +20,6 @@ export var ReactUtils;
89
20
  return String(value);
90
21
  }
91
22
  ReactUtils.formatInputValue = formatInputValue;
92
- /**
93
- * Get memory history
94
- * @param initialPath Initial path
95
- * @returns History
96
- */
97
- function getMemoryHistory(initialPath) {
98
- if (memoryHistory == null) {
99
- memoryHistory = createHistory(createMemorySource(initialPath !== null && initialPath !== void 0 ? initialPath : '/'));
100
- }
101
- return memoryHistory;
102
- }
103
- ReactUtils.getMemoryHistory = getMemoryHistory;
104
- /**
105
- * Get navigate function, works with memory history
106
- * @returns NavigateFn
107
- */
108
- function getNavigateFn() {
109
- if (memoryHistory == null)
110
- return navigate;
111
- return memoryHistory.navigate;
112
- }
113
- ReactUtils.getNavigateFn = getNavigateFn;
114
23
  /**
115
24
  * Is safe click
116
25
  * @param event Mouse event
@@ -15,7 +15,7 @@ export declare type GridAlign = 'center' | 'inherit' | 'justify' | 'left' | 'rig
15
15
  * @param align Align
16
16
  * @param type Data type
17
17
  */
18
- export declare const GridAlignGet: (align?: GridAlign | undefined, type?: DataTypes.CombinedEnum | undefined) => GridAlign | undefined;
18
+ export declare const GridAlignGet: (align?: GridAlign, type?: GridDataType) => GridAlign | undefined;
19
19
  /**
20
20
  * Grid cell value type
21
21
  */
package/lib/index.d.ts CHANGED
@@ -84,7 +84,6 @@ export * from '@etsoo/notificationbase';
84
84
  export * from './states/CultureState';
85
85
  export * from './states/IState';
86
86
  export * from './states/PageState';
87
- export * from './states/RouterProps';
88
87
  export * from './states/State';
89
88
  export * from './states/UserState';
90
89
  export * from './uses/useCombinedRefs';
package/lib/index.js CHANGED
@@ -89,7 +89,6 @@ export * from '@etsoo/notificationbase';
89
89
  export * from './states/CultureState';
90
90
  export * from './states/IState';
91
91
  export * from './states/PageState';
92
- export * from './states/RouterProps';
93
92
  export * from './states/State';
94
93
  export * from './states/UserState';
95
94
  // uses
@@ -1,7 +1,7 @@
1
1
  import { IconButton, useTheme } from '@mui/material';
2
2
  import ArrowBackIcon from '@mui/icons-material/ArrowBack';
3
3
  import React from 'react';
4
- import { ReactUtils } from '../app/ReactUtils';
4
+ import { useNavigate } from 'react-router-dom';
5
5
  /**
6
6
  * BackButton
7
7
  * @param props Props
@@ -12,6 +12,8 @@ export function BackButton(props) {
12
12
  const { color = 'primary', size = 'small', onClick, ...rest } = props;
13
13
  // Theme
14
14
  const theme = useTheme();
15
+ // Navigate
16
+ const navigate = useNavigate();
15
17
  // Color
16
18
  const pColor = color != 'inherit' && color != 'default' && color in theme.palette
17
19
  ? theme.palette[color]
@@ -21,8 +23,7 @@ export function BackButton(props) {
21
23
  if (onClick)
22
24
  onClick(event);
23
25
  // Navigate
24
- const navigate = ReactUtils.getNavigateFn();
25
- await navigate(-1);
26
+ navigate(-1);
26
27
  };
27
28
  return (React.createElement(IconButton, { "aria-label": "Back", color: color, size: size, onClick: onClickLocal, sx: {
28
29
  backgroundColor: pColor.contrastText,
@@ -1,6 +1,6 @@
1
1
  import { Button } from '@mui/material';
2
2
  import React from 'react';
3
- import { ReactUtils } from '../app/ReactUtils';
3
+ import { useNavigate } from 'react-router-dom';
4
4
  /**
5
5
  * ButtonLink
6
6
  * @param props Props
@@ -10,7 +10,7 @@ export function ButtonLink(props) {
10
10
  // Destruct
11
11
  const { href, ...rest } = props;
12
12
  // Navigate
13
- const navigate = ReactUtils.getNavigateFn();
13
+ const navigate = useNavigate();
14
14
  const onClick = href.includes('://')
15
15
  ? () => window.open(href, '_blank')
16
16
  : () => navigate(href);
package/lib/mu/FabBox.js CHANGED
@@ -18,12 +18,14 @@ export function FabBox(props) {
18
18
  ? { marginTop: spaceGap }
19
19
  : { marginLeft: spaceGap };
20
20
  // Default style
21
- Object.assign(sx, {
22
- position: 'fixed',
23
- display: 'flex',
24
- alignItems: 'center',
25
- flexDirection: columnDirection ? 'column' : 'row',
26
- '& > :not(style) + :not(style)': margin
27
- });
21
+ if (typeof sx === 'object') {
22
+ Object.assign(sx, {
23
+ position: 'fixed',
24
+ display: 'flex',
25
+ alignItems: 'center',
26
+ flexDirection: columnDirection ? 'column' : 'row',
27
+ '& > :not(style) + :not(style)': margin
28
+ });
29
+ }
28
30
  return React.createElement(Box, { sx: sx, ...rest });
29
31
  }
@@ -1,6 +1,6 @@
1
1
  import { IconButton } from '@mui/material';
2
2
  import React from 'react';
3
- import { ReactUtils } from '../app/ReactUtils';
3
+ import { useNavigate } from 'react-router-dom';
4
4
  /**
5
5
  * IconButtonLink
6
6
  * @param props Props
@@ -10,7 +10,7 @@ export function IconButtonLink(props) {
10
10
  // Destruct
11
11
  const { href, ...rest } = props;
12
12
  // Navigate
13
- const navigate = ReactUtils.getNavigateFn();
13
+ const navigate = useNavigate();
14
14
  // Layout
15
15
  return React.createElement(IconButton, { ...rest, onClick: () => navigate(href) });
16
16
  }
package/lib/mu/MoreFab.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
2
2
  import React from 'react';
3
3
  import { Divider, Fab, IconButton, ListItemIcon, ListItemText, Menu, MenuItem } from '@mui/material';
4
- import { Link } from '@reach/router';
4
+ import { Link } from 'react-router-dom';
5
5
  function getActions(input) {
6
6
  // Actions
7
7
  const actions = [];
@@ -29,7 +29,7 @@ export declare class NotifierMU extends NotifierReact {
29
29
  * @param className Style class name
30
30
  * @returns Provider
31
31
  */
32
- static setup(className?: string): React.FunctionComponent<import("../notifier/Notifier").NotificationReactRenderProps>;
32
+ static setup(className?: string): React.FunctionComponent<React.PropsWithChildren<import("../notifier/Notifier").NotificationReactRenderProps>>;
33
33
  private static getOrigin;
34
34
  /**
35
35
  * Create align container
package/lib/mu/RLink.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /// <reference types="react" />
2
2
  import { LinkProps } from '@mui/material';
3
- import { LinkProps as RouterLinkProps } from '@reach/router';
3
+ import { LinkProps as RouterLinkProps } from 'react-router-dom';
4
4
  /**
5
5
  * Router Link props
6
6
  */
7
- export declare type RLinkProps = LinkProps & RouterLinkProps<{}>;
7
+ export declare type RLinkProps = LinkProps & RouterLinkProps;
8
8
  /**
9
9
  * Router Link
10
10
  * @param props Props
package/lib/mu/RLink.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Link } from '@mui/material';
2
- import { Link as RouterLink } from '@reach/router';
2
+ import { Link as RouterLink } from 'react-router-dom';
3
3
  import React from 'react';
4
4
  /**
5
5
  * Router Link
package/lib/mu/TabBox.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Utils } from '@etsoo/shared';
2
2
  import { Box, Tab, Tabs } from '@mui/material';
3
- import { Link } from '@reach/router';
4
3
  import React from 'react';
4
+ import { Link } from 'react-router-dom';
5
5
  /**
6
6
  * Tabs with box
7
7
  * @param props Props
@@ -18,11 +18,7 @@ export const CommonPageScrollContainer = global;
18
18
  */
19
19
  export function CommonPage(props) {
20
20
  // Destruct
21
- const { children, disableGutters = true, fabButtons, fabColumnDirection, fabPaddingAdjust = 1.5, fabSize = 'small', maxWidth = false, moreActions, onRefresh, onUpdate, onUpdateAll, paddings = MUGlobal.pagePaddings, scrollContainer, supportBack = false, targetFields, sx = {}, ...rest } = props;
22
- // Merge style
23
- Object.assign(sx, {
24
- padding: paddings
25
- });
21
+ const { children, disableGutters = true, fabButtons, fabColumnDirection, fabPaddingAdjust = 1.5, fabSize = 'small', maxWidth = false, moreActions, onRefresh, onUpdate, onUpdateAll, paddings = MUGlobal.pagePaddings, scrollContainer, supportBack = false, targetFields, sx = { padding: paddings }, ...rest } = props;
26
22
  // Fab padding
27
23
  const fabPadding = MUGlobal.increase(MUGlobal.pagePaddings, fabPaddingAdjust);
28
24
  // Labels
@@ -125,6 +125,6 @@ export declare abstract class NotifierReact extends NotificationContainer<React.
125
125
  * @param className Style class name
126
126
  * @returns Provider
127
127
  */
128
- createProvider(className?: string): React.FunctionComponent<NotificationReactRenderProps>;
128
+ createProvider(className?: string): React.FunctionComponent<React.PropsWithChildren<NotificationReactRenderProps>>;
129
129
  }
130
130
  export {};
@@ -30,11 +30,11 @@ export declare class CultureState {
30
30
  /**
31
31
  * Context
32
32
  */
33
- readonly context: React.Context<CultureCalls>;
33
+ readonly context: import("react").Context<CultureCalls>;
34
34
  /**
35
35
  * Provider
36
36
  */
37
- readonly provider: React.FunctionComponent<CultureProviderProps>;
37
+ readonly provider: import("react").FunctionComponent<import("react").PropsWithChildren<IProviderProps<CultureAction>>>;
38
38
  /**
39
39
  * Constructor
40
40
  */
@@ -1,5 +1,5 @@
1
1
  import { IAction, IState, UserKey } from '@etsoo/appscript';
2
- import React, { ReactNode } from 'react';
2
+ import React from 'react';
3
3
  /**
4
4
  * State UI creator
5
5
  */
@@ -42,10 +42,6 @@ export interface IProviderUpdate<A extends IAction> {
42
42
  * State provider props
43
43
  */
44
44
  export interface IProviderProps<A extends IAction> {
45
- /**
46
- * Children
47
- */
48
- children?: ReactNode | undefined;
49
45
  /**
50
46
  * Update callback
51
47
  */
@@ -46,11 +46,11 @@ export declare class PageState<D extends IPageData> {
46
46
  /**
47
47
  * Context
48
48
  */
49
- readonly context: React.Context<PageCalls<D>>;
49
+ readonly context: import("react").Context<PageCalls<D>>;
50
50
  /**
51
51
  * Provider
52
52
  */
53
- readonly provider: React.FunctionComponent<PageProviderProps<D>>;
53
+ readonly provider: import("react").FunctionComponent<import("react").PropsWithChildren<IProviderProps<PageAction<D>>>>;
54
54
  /**
55
55
  * Constructor
56
56
  */
@@ -13,6 +13,6 @@ export declare class State {
13
13
  */
14
14
  static create<S extends IState, A extends IAction, U extends IUpdate<S, A>, P extends IProviderProps<A>>(reducer: React.Reducer<S, A>, initState: S, calls: U, uiCreator?: IUICreator<S, A, P>): {
15
15
  context: React.Context<U>;
16
- provider: React.FunctionComponent<P>;
16
+ provider: React.FunctionComponent<React.PropsWithChildren<P>>;
17
17
  };
18
18
  }
@@ -44,11 +44,11 @@ export declare class UserState<D extends IUser> {
44
44
  /**
45
45
  * Context
46
46
  */
47
- readonly context: React.Context<UserCalls<D>>;
47
+ readonly context: import("react").Context<UserCalls<D>>;
48
48
  /**
49
49
  * Provider
50
50
  */
51
- readonly provider: React.FunctionComponent<UserProviderProps<D>>;
51
+ readonly provider: import("react").FunctionComponent<import("react").PropsWithChildren<IProviderProps<UserAction<D>>>>;
52
52
  /**
53
53
  * Constructor
54
54
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.5.31",
3
+ "version": "1.5.34",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -55,10 +55,8 @@
55
55
  "@etsoo/shared": "^1.1.38",
56
56
  "@mui/icons-material": "^5.8.0",
57
57
  "@mui/material": "^5.8.1",
58
- "@reach/router": "^1.3.4",
59
58
  "@types/pica": "^9.0.0",
60
59
  "@types/pulltorefreshjs": "^0.1.5",
61
- "@types/reach__router": "^1.3.10",
62
60
  "@types/react": "^18.0.9",
63
61
  "@types/react-avatar-editor": "^12.0.0",
64
62
  "@types/react-beautiful-dnd": "^13.1.2",
@@ -73,6 +71,7 @@
73
71
  "react-dom": "^18.1.0",
74
72
  "react-draggable": "^4.4.5",
75
73
  "react-imask": "^6.4.2",
74
+ "react-router-dom": "^6.3.0",
76
75
  "react-window": "^1.8.7"
77
76
  },
78
77
  "devDependencies": {
@@ -93,6 +92,6 @@
93
92
  "jest-environment-jsdom": "^28.1.0",
94
93
  "react-test-renderer": "^18.1.0",
95
94
  "ts-jest": "^28.0.3",
96
- "typescript": "^4.6.4"
95
+ "typescript": "^4.7.2"
97
96
  }
98
97
  }
@@ -15,7 +15,6 @@ import {
15
15
  NotificationReturn
16
16
  } from '@etsoo/notificationbase';
17
17
  import { DataTypes, WindowStorage } from '@etsoo/shared';
18
- import { History } from '@reach/router';
19
18
  import React from 'react';
20
19
  import { NotifierMU } from '../mu/NotifierMU';
21
20
  import { ProgressCount } from '../mu/ProgressCount';
@@ -37,6 +36,7 @@ import {
37
36
  import { InputDialogProps } from './InputDialogProps';
38
37
  import { Labels } from './Labels';
39
38
  import { ReactUtils } from './ReactUtils';
39
+ import { createBrowserHistory, createMemoryHistory, History } from 'history';
40
40
 
41
41
  /**
42
42
  * Global application
@@ -101,7 +101,7 @@ export interface IReactApp<
101
101
  /**
102
102
  * Router history
103
103
  */
104
- readonly history?: History;
104
+ readonly history: History;
105
105
 
106
106
  /**
107
107
  * Is screen size down 'sm'
@@ -175,7 +175,7 @@ export class ReactApp<
175
175
  /**
176
176
  * Router history
177
177
  */
178
- readonly history?: History;
178
+ readonly history: History;
179
179
 
180
180
  /**
181
181
  * Page state
@@ -221,12 +221,12 @@ export class ReactApp<
221
221
  name
222
222
  );
223
223
 
224
- this.history =
225
- BridgeUtils.host == null
226
- ? undefined
227
- : ReactUtils.getMemoryHistory(BridgeUtils.host.getStartUrl());
228
-
229
224
  if (BridgeUtils.host) {
225
+ const startUrl = BridgeUtils.host.getStartUrl();
226
+ this.history = createMemoryHistory({
227
+ initialEntries: startUrl == null ? undefined : [startUrl]
228
+ });
229
+
230
230
  BridgeUtils.host.onUpdate((app, version) => {
231
231
  this.notifier.message(
232
232
  NotificationMessageType.Success,
@@ -234,6 +234,8 @@ export class ReactApp<
234
234
  this.get('updateReady')
235
235
  );
236
236
  });
237
+ } else {
238
+ this.history = createBrowserHistory();
237
239
  }
238
240
 
239
241
  this.cultureState = new CultureState(settings.currentCulture);
@@ -381,8 +383,7 @@ export class ReactApp<
381
383
  * @param url Url
382
384
  */
383
385
  override redirectTo(url: string) {
384
- const navigate = ReactUtils.getNavigateFn();
385
- navigate(url);
386
+ this.history.push(url);
386
387
  }
387
388
 
388
389
  /**
@@ -1,98 +1,9 @@
1
- import { createHistory, History, HistorySource, navigate } from '@reach/router';
2
1
  import React from 'react';
3
2
 
4
- type MemoryHistorySource = HistorySource & {
5
- history: {
6
- get entries(): any;
7
- get index(): number;
8
- go(to: number): void;
9
- };
10
- };
11
-
12
3
  /**
13
4
  * React utils
14
5
  */
15
6
  export namespace ReactUtils {
16
- // Memory history
17
- // https://github.com/reach/router/issues/225
18
- let memoryHistory: History | null;
19
-
20
- /**
21
- * Cretae memory source to fix go back bug
22
- * @param initialPath Initial path
23
- */
24
- export function createMemorySource(
25
- initialPath: string = '/'
26
- ): MemoryHistorySource {
27
- const searchIndex = initialPath.indexOf('?');
28
- const pathname =
29
- searchIndex > -1
30
- ? initialPath.substring(0, searchIndex)
31
- : initialPath;
32
-
33
- const initialLocation: any = {
34
- pathname,
35
- search: searchIndex > -1 ? initialPath.substring(searchIndex) : ''
36
- };
37
-
38
- let index = 0;
39
-
40
- const stack = [initialLocation];
41
- const states = [null];
42
-
43
- return {
44
- get location() {
45
- return stack[index];
46
- },
47
- addEventListener(name, fn) {},
48
- removeEventListener(name, fn) {},
49
- history: {
50
- get entries() {
51
- return stack;
52
- },
53
- get index() {
54
- return index;
55
- },
56
- get state() {
57
- return states[index];
58
- },
59
- pushState(state, _, uri) {
60
- const [pathname, search = ''] = uri.split('?');
61
- index++;
62
-
63
- // View a, index = 0
64
- // View b, index = 1
65
- // Go(-1), a, index = 0
66
- // View c, index = 1, directly push is wrong
67
- if (index < stack.length) {
68
- stack.splice(index);
69
- states.splice(index);
70
- }
71
-
72
- stack.push({
73
- pathname,
74
- search: search.length ? `?${search}` : search
75
- });
76
- states.push(state);
77
- },
78
- replaceState(state, _, uri) {
79
- const [pathname, search = ''] = uri.split('?');
80
- stack[index] = { pathname, search };
81
- states[index] = state;
82
- },
83
- go(to: number) {
84
- const newIndex = index + to;
85
-
86
- if (newIndex < 0 || newIndex > states.length - 1) {
87
- return;
88
- }
89
-
90
- index = newIndex;
91
- }
92
- }
93
- };
94
- }
95
-
96
7
  /**
97
8
  * Format input value
98
9
  * @param value Input value
@@ -110,29 +21,6 @@ export namespace ReactUtils {
110
21
  return String(value);
111
22
  }
112
23
 
113
- /**
114
- * Get memory history
115
- * @param initialPath Initial path
116
- * @returns History
117
- */
118
- export function getMemoryHistory(initialPath?: string | null) {
119
- if (memoryHistory == null) {
120
- memoryHistory = createHistory(
121
- createMemorySource(initialPath ?? '/')
122
- );
123
- }
124
- return memoryHistory;
125
- }
126
-
127
- /**
128
- * Get navigate function, works with memory history
129
- * @returns NavigateFn
130
- */
131
- export function getNavigateFn() {
132
- if (memoryHistory == null) return navigate;
133
- return memoryHistory.navigate;
134
- }
135
-
136
24
  /**
137
25
  * Is safe click
138
26
  * @param event Mouse event
package/src/index.ts CHANGED
@@ -95,7 +95,6 @@ export * from '@etsoo/notificationbase';
95
95
  export * from './states/CultureState';
96
96
  export * from './states/IState';
97
97
  export * from './states/PageState';
98
- export * from './states/RouterProps';
99
98
  export * from './states/State';
100
99
  export * from './states/UserState';
101
100
 
@@ -1,7 +1,7 @@
1
1
  import { IconButton, IconButtonProps, useTheme } from '@mui/material';
2
2
  import ArrowBackIcon from '@mui/icons-material/ArrowBack';
3
3
  import React from 'react';
4
- import { ReactUtils } from '../app/ReactUtils';
4
+ import { useNavigate } from 'react-router-dom';
5
5
 
6
6
  /**
7
7
  * BackButton props
@@ -20,6 +20,9 @@ export function BackButton(props: BackButtonProps) {
20
20
  // Theme
21
21
  const theme = useTheme();
22
22
 
23
+ // Navigate
24
+ const navigate = useNavigate();
25
+
23
26
  // Color
24
27
  const pColor =
25
28
  color != 'inherit' && color != 'default' && color in theme.palette
@@ -31,8 +34,7 @@ export function BackButton(props: BackButtonProps) {
31
34
  if (onClick) onClick(event);
32
35
 
33
36
  // Navigate
34
- const navigate = ReactUtils.getNavigateFn();
35
- await navigate(-1);
37
+ navigate(-1);
36
38
  };
37
39
 
38
40
  return (
@@ -1,7 +1,6 @@
1
1
  import { Button, ButtonProps } from '@mui/material';
2
2
  import React from 'react';
3
- import { ReactUtils } from '../app/ReactUtils';
4
-
3
+ import { useNavigate } from 'react-router-dom';
5
4
  /**
6
5
  * ButtonLink props
7
6
  */
@@ -22,7 +21,7 @@ export function ButtonLink(props: ButtonLinkProps) {
22
21
  const { href, ...rest } = props;
23
22
 
24
23
  // Navigate
25
- const navigate = ReactUtils.getNavigateFn();
24
+ const navigate = useNavigate();
26
25
 
27
26
  const onClick = href.includes('://')
28
27
  ? () => window.open(href, '_blank')
package/src/mu/FabBox.tsx CHANGED
@@ -37,13 +37,15 @@ export function FabBox(props: FabBoxProps) {
37
37
  : { marginLeft: spaceGap };
38
38
 
39
39
  // Default style
40
- Object.assign(sx, {
41
- position: 'fixed',
42
- display: 'flex',
43
- alignItems: 'center',
44
- flexDirection: columnDirection ? 'column' : 'row',
45
- '& > :not(style) + :not(style)': margin
46
- });
40
+ if (typeof sx === 'object') {
41
+ Object.assign(sx as any, {
42
+ position: 'fixed',
43
+ display: 'flex',
44
+ alignItems: 'center',
45
+ flexDirection: columnDirection ? 'column' : 'row',
46
+ '& > :not(style) + :not(style)': margin
47
+ });
48
+ }
47
49
 
48
50
  return <Box sx={sx} {...rest} />;
49
51
  }
@@ -1,6 +1,6 @@
1
1
  import { IconButton, IconButtonProps } from '@mui/material';
2
2
  import React from 'react';
3
- import { ReactUtils } from '../app/ReactUtils';
3
+ import { useNavigate } from 'react-router-dom';
4
4
 
5
5
  /**
6
6
  * IconButtonLink props
@@ -22,7 +22,7 @@ export function IconButtonLink(props: IconButtonLinkProps) {
22
22
  const { href, ...rest } = props;
23
23
 
24
24
  // Navigate
25
- const navigate = ReactUtils.getNavigateFn();
25
+ const navigate = useNavigate();
26
26
 
27
27
  // Layout
28
28
  return <IconButton {...rest} onClick={() => navigate(href)} />;
@@ -13,7 +13,7 @@ import {
13
13
  PopoverOrigin
14
14
  } from '@mui/material';
15
15
  import { ListItemReact } from '../components/ListItemReact';
16
- import { Link } from '@reach/router';
16
+ import { Link } from 'react-router-dom';
17
17
 
18
18
  /**
19
19
  * More fab props
package/src/mu/RLink.tsx CHANGED
@@ -2,13 +2,13 @@ import { Link, LinkProps } from '@mui/material';
2
2
  import {
3
3
  Link as RouterLink,
4
4
  LinkProps as RouterLinkProps
5
- } from '@reach/router';
5
+ } from 'react-router-dom';
6
6
  import React from 'react';
7
7
 
8
8
  /**
9
9
  * Router Link props
10
10
  */
11
- export type RLinkProps = LinkProps & RouterLinkProps<{}>;
11
+ export type RLinkProps = LinkProps & RouterLinkProps;
12
12
 
13
13
  /**
14
14
  * Router Link
package/src/mu/TabBox.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Utils } from '@etsoo/shared';
2
2
  import { Box, BoxProps, Tab, TabProps, Tabs, TabsProps } from '@mui/material';
3
- import { Link } from '@reach/router';
4
3
  import React from 'react';
4
+ import { Link } from 'react-router-dom';
5
5
 
6
6
  /**
7
7
  * Tab with box panel props
@@ -37,15 +37,10 @@ export function CommonPage(props: CommonPageProps) {
37
37
  scrollContainer,
38
38
  supportBack = false,
39
39
  targetFields,
40
- sx = {},
40
+ sx = { padding: paddings },
41
41
  ...rest
42
42
  } = props;
43
43
 
44
- // Merge style
45
- Object.assign(sx, {
46
- padding: paddings
47
- });
48
-
49
44
  // Fab padding
50
45
  const fabPadding = MUGlobal.increase(
51
46
  MUGlobal.pagePaddings,
@@ -46,12 +46,12 @@ export class CultureState {
46
46
  /**
47
47
  * Context
48
48
  */
49
- readonly context: React.Context<CultureCalls>;
49
+ readonly context;
50
50
 
51
51
  /**
52
52
  * Provider
53
53
  */
54
- readonly provider: React.FunctionComponent<CultureProviderProps>;
54
+ readonly provider;
55
55
 
56
56
  /**
57
57
  * Constructor
@@ -49,11 +49,6 @@ export interface IProviderUpdate<A extends IAction> {
49
49
  * State provider props
50
50
  */
51
51
  export interface IProviderProps<A extends IAction> {
52
- /**
53
- * Children
54
- */
55
- children?: ReactNode | undefined;
56
-
57
52
  /**
58
53
  * Update callback
59
54
  */
@@ -58,12 +58,12 @@ export class PageState<D extends IPageData> {
58
58
  /**
59
59
  * Context
60
60
  */
61
- readonly context: React.Context<PageCalls<D>>;
61
+ readonly context;
62
62
 
63
63
  /**
64
64
  * Provider
65
65
  */
66
- readonly provider: React.FunctionComponent<PageProviderProps<D>>;
66
+ readonly provider;
67
67
 
68
68
  /**
69
69
  * Constructor
@@ -27,7 +27,9 @@ export class State {
27
27
  const context = React.createContext(calls);
28
28
 
29
29
  // State context provider
30
- const provider: React.FunctionComponent<P> = (props) => {
30
+ const provider: React.FunctionComponent<React.PropsWithChildren<P>> = (
31
+ props
32
+ ) => {
31
33
  // Destruct
32
34
  const { children, update } = props;
33
35
 
@@ -58,12 +58,12 @@ export class UserState<D extends IUser> {
58
58
  /**
59
59
  * Context
60
60
  */
61
- readonly context: React.Context<UserCalls<D>>;
61
+ readonly context;
62
62
 
63
63
  /**
64
64
  * Provider
65
65
  */
66
- readonly provider: React.FunctionComponent<UserProviderProps<D>>;
66
+ readonly provider;
67
67
 
68
68
  /**
69
69
  * Constructor
@@ -1,39 +0,0 @@
1
- import { DataTypes } from '@etsoo/shared';
2
- import { RouteComponentProps } from '@reach/router';
3
- /**
4
- * Add / Edit page router props, include 'id' (/:id) or none when adding query parameter
5
- */
6
- export declare type EditPageRouterProps = IdRouterProps & WildcardRouterProps;
7
- /**
8
- * Get edit page id
9
- * @param props Route props
10
- * @param type Target data type
11
- * @returns Data
12
- */
13
- export declare function getEditPageId<T extends DataTypes.BasicNames>(props: EditPageRouterProps, type: T): DataTypes.BasicConditional<T> | undefined;
14
- /**
15
- * Id router props, include 'id' (/:id) query parameter
16
- */
17
- export declare type IdRouterProps = RouteComponentProps<{
18
- id: string;
19
- }>;
20
- /**
21
- * Wildcard router props, (/*) query parameter
22
- */
23
- export declare type WildcardRouterProps = RouteComponentProps<{
24
- '*': string;
25
- }>;
26
- /**
27
- * Id state router props, include 'id' in location.state
28
- */
29
- export declare type IdStateRouterProps<T extends DataTypes.IdType = number> = StateRouterProps<{
30
- id: T;
31
- }>;
32
- /**
33
- * State router props, include data in location.state
34
- */
35
- export declare type StateRouterProps<T extends Readonly<DataTypes.StringRecord>> = RouteComponentProps<{
36
- location: {
37
- state: T;
38
- };
39
- }>;
@@ -1,14 +0,0 @@
1
- import { DataTypes } from '@etsoo/shared';
2
- /**
3
- * Get edit page id
4
- * @param props Route props
5
- * @param type Target data type
6
- * @returns Data
7
- */
8
- export function getEditPageId(props, type) {
9
- var _a;
10
- const id = (_a = props.id) !== null && _a !== void 0 ? _a : props['*'];
11
- if (id == null || id === '')
12
- return undefined;
13
- return DataTypes.convertByType(id, type);
14
- }
@@ -1,46 +0,0 @@
1
- import { DataTypes } from '@etsoo/shared';
2
- import { RouteComponentProps } from '@reach/router';
3
-
4
- /**
5
- * Add / Edit page router props, include 'id' (/:id) or none when adding query parameter
6
- */
7
- export type EditPageRouterProps = IdRouterProps & WildcardRouterProps;
8
-
9
- /**
10
- * Get edit page id
11
- * @param props Route props
12
- * @param type Target data type
13
- * @returns Data
14
- */
15
- export function getEditPageId<T extends DataTypes.BasicNames>(
16
- props: EditPageRouterProps,
17
- type: T
18
- ): DataTypes.BasicConditional<T> | undefined {
19
- const id = props.id ?? props['*'];
20
- if (id == null || id === '') return undefined;
21
- return DataTypes.convertByType(id, type);
22
- }
23
-
24
- /**
25
- * Id router props, include 'id' (/:id) query parameter
26
- */
27
- export type IdRouterProps = RouteComponentProps<{ id: string }>;
28
-
29
- /**
30
- * Wildcard router props, (/*) query parameter
31
- */
32
- export type WildcardRouterProps = RouteComponentProps<{ '*': string }>;
33
-
34
- /**
35
- * Id state router props, include 'id' in location.state
36
- */
37
- export type IdStateRouterProps<T extends DataTypes.IdType = number> =
38
- StateRouterProps<{ id: T }>;
39
-
40
- /**
41
- * State router props, include data in location.state
42
- */
43
- export type StateRouterProps<T extends Readonly<DataTypes.StringRecord>> =
44
- RouteComponentProps<{
45
- location: { state: T };
46
- }>;