@arcblock/ux 2.10.67 → 2.10.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Address/did-address.d.ts +6 -5
- package/lib/Address/index.d.ts +1 -1
- package/lib/Avatar/index.d.ts +10 -8
- package/lib/Avatar/index.js +6 -4
- package/lib/Blocklet/blocklet.d.ts +4 -4
- package/lib/Blocklet/blocklet.js +2 -2
- package/lib/BlockletContext/index.d.ts +3 -3
- package/lib/BlockletNFT/index.d.ts +6 -6
- package/lib/BlockletNFT/index.js +3 -3
- package/lib/BlockletV2/blocklet.d.ts +2 -2
- package/lib/Button/wrap.d.ts +4 -4
- package/lib/Button/wrap.js +2 -2
- package/lib/CardSelector/index.js +0 -1
- package/lib/Center/index.d.ts +1 -1
- package/lib/ClickToCopy/copy-button.d.ts +5 -4
- package/lib/ClickToCopy/copy-button.js +0 -1
- package/lib/ClickToCopy/hook.d.ts +3 -8
- package/lib/ClickToCopy/index.d.ts +6 -4
- package/lib/CodeBlock/index.d.ts +3 -1
- package/lib/CookieConsent/index.d.ts +8 -29
- package/lib/CookieConsent/index.js +3 -17
- package/lib/CountDown/index.d.ts +21 -25
- package/lib/CountDown/index.js +12 -11
- package/lib/DID/index.d.ts +9 -8
- package/lib/Datatable/index.d.ts +5 -5
- package/lib/Datatable/index.js +5 -5
- package/lib/Dialog/confirm.d.ts +6 -6
- package/lib/Dialog/confirm.js +3 -3
- package/lib/Dialog/types.d.ts +1 -1
- package/lib/DidLogo/index.d.ts +5 -25
- package/lib/DidLogo/index.js +4 -15
- package/lib/DriftBot/index.d.ts +13 -19
- package/lib/DriftBot/index.js +5 -6
- package/lib/Earth/index.d.ts +28 -10
- package/lib/Earth/index.js +12 -52
- package/lib/Earth/util.d.ts +10 -5
- package/lib/Earth/util.js +1 -0
- package/lib/ErrorBoundary/fallback.d.ts +12 -19
- package/lib/ErrorBoundary/fallback.js +2 -19
- package/lib/ErrorBoundary/index.d.ts +1 -1
- package/lib/Footer/index.d.ts +17 -24
- package/lib/Footer/index.js +2 -11
- package/lib/Header/header.d.ts +2 -2
- package/lib/Icon/image.d.ts +3 -2
- package/lib/Icon/index.d.ts +6 -4
- package/lib/Img/index.d.ts +1 -1
- package/lib/Img/index.js +1 -1
- package/lib/InfoRow/index.d.ts +9 -32
- package/lib/InfoRow/index.js +10 -23
- package/lib/Layout/dashboard/external-link.d.ts +13 -14
- package/lib/Layout/dashboard/external-link.js +5 -22
- package/lib/Layout/dashboard/full-page.d.ts +19 -11
- package/lib/Layout/dashboard/full-page.js +2 -6
- package/lib/Layout/dashboard/index.d.ts +20 -39
- package/lib/Layout/dashboard/index.js +10 -38
- package/lib/Layout/dashboard/sidebar.d.ts +17 -20
- package/lib/Layout/dashboard/sidebar.js +3 -16
- package/lib/Layout/dashboard-legacy/header.d.ts +10 -36
- package/lib/Layout/dashboard-legacy/header.js +5 -24
- package/lib/Layout/dashboard-legacy/index.d.ts +17 -56
- package/lib/Layout/dashboard-legacy/index.js +12 -41
- package/lib/Layout/dashboard-legacy/sidebar.d.ts +15 -26
- package/lib/Layout/dashboard-legacy/sidebar.js +5 -15
- package/lib/Layout/index.d.ts +17 -56
- package/lib/Layout/index.js +24 -50
- package/lib/LoadingMask/index.d.ts +8 -31
- package/lib/LoadingMask/index.js +3 -19
- package/lib/Locale/browser-lang.d.ts +4 -1
- package/lib/Locale/browser-lang.js +8 -3
- package/lib/Locale/context.d.ts +18 -8
- package/lib/Locale/context.js +1 -1
- package/lib/Locale/languages.d.ts +9 -55
- package/lib/Locale/selector.d.ts +10 -26
- package/lib/Locale/selector.js +8 -25
- package/lib/Locale/util.d.ts +4 -3
- package/lib/Locale/util.js +0 -1
- package/lib/Logo/index.d.ts +9 -40
- package/lib/Logo/index.js +88 -46
- package/lib/Metric/index.d.ts +9 -31
- package/lib/Metric/index.js +5 -20
- package/lib/NFTDisplay/aspect-ratio-container.d.ts +5 -12
- package/lib/NFTDisplay/aspect-ratio-container.js +0 -5
- package/lib/NFTDisplay/broken.d.ts +3 -13
- package/lib/NFTDisplay/broken.js +80 -10
- package/lib/NFTDisplay/displayApi.d.ts +1 -1
- package/lib/NFTDisplay/index.d.ts +28 -6
- package/lib/NFTDisplay/index.js +17 -51
- package/lib/NFTDisplay/svg-embedder/img.d.ts +8 -23
- package/lib/NFTDisplay/svg-embedder/img.js +3 -17
- package/lib/NFTDisplay/svg-embedder/inline-svg.d.ts +7 -13
- package/lib/NFTDisplay/svg-embedder/inline-svg.js +1 -8
- package/lib/NavMenu/nav-menu.d.ts +2 -0
- package/lib/NavMenu/nav-menu.js +0 -1
- package/lib/PageScroller/index.d.ts +14 -13
- package/lib/PageScroller/index.js +12 -37
- package/lib/PageScroller/usePrevValue.d.ts +1 -1
- package/lib/PageScroller/usePrevValue.js +1 -2
- package/lib/Passport/index.d.ts +1 -1
- package/lib/Passport/passport.d.ts +10 -30
- package/lib/Passport/passport.js +5 -19
- package/lib/PoweredByArcBlock/index.d.ts +4 -14
- package/lib/PoweredByArcBlock/index.js +1 -8
- package/lib/PricingTable/PricingPlan.d.ts +11 -9
- package/lib/PricingTable/PricingPlan.js +0 -4
- package/lib/PricingTable/index.d.ts +5 -3
- package/lib/PricingTable/index.js +1 -5
- package/lib/QRCode/index.d.ts +11 -22
- package/lib/QRCode/index.js +2 -17
- package/lib/RelativeTime/index.d.ts +12 -40
- package/lib/RelativeTime/index.js +7 -27
- package/lib/Result/common.d.ts +26 -45
- package/lib/Result/common.js +2 -4
- package/lib/Result/index.d.ts +5 -18
- package/lib/Result/index.js +1 -9
- package/lib/Result/result.d.ts +7 -29
- package/lib/Result/result.js +2 -17
- package/lib/Result/translations.d.ts +2 -54
- package/lib/Screenshot/BaseScreenshot/index.d.ts +7 -24
- package/lib/Screenshot/BaseScreenshot/index.js +2 -15
- package/lib/Screenshot/BaseScreenshot/shells/Macbook.d.ts +25 -19
- package/lib/Screenshot/BaseScreenshot/shells/Phone.d.ts +25 -19
- package/lib/Screenshot/index.d.ts +84 -28
- package/lib/Screenshot/index.js +14 -43
- package/lib/SessionBlocklet/index.d.ts +6 -19
- package/lib/SessionBlocklet/index.js +5 -15
- package/lib/SessionManager/index.d.ts +1 -1
- package/lib/SessionPermission/index.d.ts +9 -17
- package/lib/SessionPermission/index.js +3 -11
- package/lib/SessionUser/components/logged-in.d.ts +9 -31
- package/lib/SessionUser/components/logged-in.js +13 -29
- package/lib/SessionUser/components/session-user-item.d.ts +8 -1
- package/lib/SessionUser/components/session-user-item.js +2 -12
- package/lib/SessionUser/components/session-user-switch.d.ts +9 -21
- package/lib/SessionUser/components/session-user-switch.js +3 -15
- package/lib/SessionUser/components/un-login.d.ts +7 -23
- package/lib/SessionUser/components/un-login.js +4 -16
- package/lib/SessionUser/components/user-info.d.ts +12 -29
- package/lib/SessionUser/components/user-info.js +4 -19
- package/lib/SessionUser/index.d.ts +7 -30
- package/lib/SessionUser/index.js +5 -26
- package/lib/SessionUser/libs/translation.d.ts +2 -31
- package/lib/SessionUser/libs/translation.js +1 -0
- package/lib/SessionUser/libs/utils.d.ts +10 -9
- package/lib/Sparkline/index.d.ts +22 -1
- package/lib/Sparkline/index.js +25 -17
- package/lib/Spinner/index.d.ts +6 -1
- package/lib/Spinner/index.js +4 -11
- package/lib/Success/index.d.ts +5 -21
- package/lib/Success/index.js +10 -19
- package/lib/Tabs/index.d.ts +12 -26
- package/lib/Tabs/index.js +7 -37
- package/lib/TextCollapse/index.d.ts +10 -10
- package/lib/TextCollapse/index.js +4 -21
- package/lib/Theme/index.js +0 -2
- package/lib/Theme/theme-provider.d.ts +1 -1
- package/lib/Theme/theme.d.ts +4 -1
- package/lib/Theme/theme.js +1 -2
- package/lib/Typography/index.d.ts +5 -24
- package/lib/Typography/index.js +5 -17
- package/lib/Util/index.d.ts +17 -8
- package/lib/Util/index.js +22 -3
- package/lib/Video/index.d.ts +12 -16
- package/lib/Video/index.js +0 -14
- package/lib/Wallet/Action.d.ts +13 -18
- package/lib/Wallet/Action.js +0 -7
- package/lib/Wallet/Download.d.ts +24 -30
- package/lib/Wallet/Download.js +201 -18
- package/lib/Wallet/Open.d.ts +5 -15
- package/lib/Wallet/Open.js +5 -11
- package/lib/WalletOSIcon/index.d.ts +6 -25
- package/lib/WalletOSIcon/index.js +3 -16
- package/lib/WebWalletSWKeeper/index.d.ts +8 -20
- package/lib/WebWalletSWKeeper/index.js +14 -19
- package/lib/WechatPrompt/index.js +2 -0
- package/lib/global.d.ts +15 -0
- package/lib/type.d.ts +12 -3
- package/lib/withTheme/index.d.ts +8 -6
- package/lib/withTracker/index.d.ts +1 -1
- package/lib/withTracker/index.js +3 -0
- package/package.json +9 -5
- package/src/Address/did-address.tsx +7 -6
- package/src/Address/index.tsx +1 -1
- package/src/Avatar/index.jsx +6 -4
- package/src/Blocklet/blocklet.jsx +2 -2
- package/src/BlockletContext/index.tsx +3 -3
- package/src/BlockletNFT/index.jsx +3 -3
- package/src/BlockletV2/blocklet.tsx +2 -2
- package/src/Button/wrap.jsx +2 -2
- package/src/CardSelector/index.tsx +0 -1
- package/src/Center/index.tsx +1 -1
- package/src/ClickToCopy/copy-button.tsx +4 -4
- package/src/ClickToCopy/hook.ts +3 -2
- package/src/ClickToCopy/index.tsx +6 -5
- package/src/CodeBlock/index.tsx +3 -1
- package/src/CookieConsent/{index.jsx → index.tsx} +16 -19
- package/src/CountDown/{index.jsx → index.tsx} +30 -16
- package/src/DID/index.tsx +9 -8
- package/src/Datatable/index.jsx +5 -5
- package/src/Dialog/confirm.jsx +3 -3
- package/src/Dialog/types.d.ts +1 -1
- package/src/DidLogo/{index.jsx → index.tsx} +7 -14
- package/src/DriftBot/{index.jsx → index.tsx} +13 -11
- package/src/Earth/{index.jsx → index.tsx} +94 -66
- package/src/Earth/{util.js → util.ts} +20 -17
- package/src/ErrorBoundary/{fallback.jsx → fallback.tsx} +20 -21
- package/src/Footer/{index.jsx → index.tsx} +17 -14
- package/src/Header/header.tsx +2 -3
- package/src/Header/responsive-header.tsx +0 -1
- package/src/Icon/image.tsx +3 -3
- package/src/Icon/index.tsx +7 -4
- package/src/Img/index.jsx +1 -1
- package/src/InfoRow/{index.jsx → index.tsx} +32 -25
- package/src/Layout/dashboard/external-link.tsx +46 -0
- package/src/Layout/dashboard/{full-page.jsx → full-page.tsx} +20 -9
- package/src/Layout/dashboard/{index.jsx → index.tsx} +42 -44
- package/src/Layout/dashboard/{sidebar.jsx → sidebar.tsx} +23 -20
- package/src/Layout/dashboard-legacy/{header.jsx → header.tsx} +16 -26
- package/src/Layout/dashboard-legacy/{index.jsx → index.tsx} +32 -46
- package/src/Layout/dashboard-legacy/{sidebar.jsx → sidebar.tsx} +27 -19
- package/src/Layout/{index.jsx → index.tsx} +41 -47
- package/src/LoadingMask/{index.jsx → index.tsx} +18 -20
- package/src/Locale/{browser-lang.js → browser-lang.ts} +9 -7
- package/src/Locale/context.tsx +18 -11
- package/src/Locale/{languages.js → languages.ts} +1 -1
- package/src/Locale/{selector.jsx → selector.tsx} +32 -29
- package/src/Locale/{util.js → util.ts} +9 -2
- package/src/Logo/index.tsx +58 -0
- package/src/Metric/{index.jsx → index.tsx} +23 -18
- package/src/NFTDisplay/{aspect-ratio-container.jsx → aspect-ratio-container.tsx} +9 -7
- package/src/NFTDisplay/{broken.jsx → broken.tsx} +7 -12
- package/src/NFTDisplay/{displayApi.js → displayApi.ts} +4 -4
- package/src/NFTDisplay/{index.jsx → index.tsx} +59 -64
- package/src/NFTDisplay/svg-embedder/{img.jsx → img.tsx} +10 -18
- package/src/NFTDisplay/svg-embedder/{inline-svg.jsx → inline-svg.tsx} +8 -9
- package/src/NavMenu/nav-menu.tsx +2 -3
- package/src/PageScroller/{index.jsx → index.tsx} +40 -53
- package/src/PageScroller/{usePrevValue.js → usePrevValue.ts} +2 -3
- package/src/Passport/{passport.jsx → passport.tsx} +22 -19
- package/src/PoweredByArcBlock/{index.jsx → index.tsx} +6 -11
- package/src/PricingTable/{PricingPlan.jsx → PricingPlan.tsx} +15 -5
- package/src/PricingTable/{index.jsx → index.tsx} +9 -6
- package/src/QRCode/{index.jsx → index.tsx} +14 -19
- package/src/RelativeTime/{index.jsx → index.tsx} +24 -24
- package/src/Result/{common.jsx → common.tsx} +17 -13
- package/src/Result/index.tsx +30 -0
- package/src/Result/{result.jsx → result.tsx} +8 -17
- package/src/Result/{translations.js → translations.ts} +3 -1
- package/src/Screenshot/BaseScreenshot/{index.jsx → index.tsx} +9 -15
- package/src/Screenshot/BaseScreenshot/shells/{Macbook.jsx → Macbook.tsx} +3 -1
- package/src/Screenshot/BaseScreenshot/shells/{Phone.jsx → Phone.tsx} +3 -1
- package/src/Screenshot/{index.jsx → index.tsx} +60 -54
- package/src/SessionBlocklet/{index.jsx → index.tsx} +9 -14
- package/src/SessionPermission/index.tsx +25 -0
- package/src/SessionUser/components/{logged-in.jsx → logged-in.tsx} +49 -31
- package/src/SessionUser/components/session-user-item.tsx +97 -0
- package/src/SessionUser/components/{session-user-switch.jsx → session-user-switch.tsx} +16 -21
- package/src/SessionUser/components/{un-login.jsx → un-login.tsx} +10 -15
- package/src/SessionUser/components/{user-info.jsx → user-info.tsx} +16 -22
- package/src/SessionUser/index.tsx +26 -0
- package/src/SessionUser/libs/{translation.js → translation.ts} +3 -1
- package/src/SessionUser/libs/utils.ts +39 -0
- package/src/Sparkline/{index.jsx → index.tsx} +38 -22
- package/src/Spinner/index.tsx +20 -0
- package/src/Success/{index.jsx → index.tsx} +13 -16
- package/src/Tabs/{index.jsx → index.tsx} +26 -40
- package/src/TextCollapse/{index.jsx → index.tsx} +26 -21
- package/src/Theme/index.ts +0 -1
- package/src/Theme/theme-provider.tsx +1 -1
- package/src/Theme/theme.ts +6 -3
- package/src/Typography/{index.jsx → index.tsx} +19 -22
- package/src/Util/index.ts +26 -9
- package/src/Video/{index.jsx → index.tsx} +7 -10
- package/src/Wallet/{Action.jsx → Action.tsx} +16 -12
- package/src/Wallet/{Download.jsx → Download.tsx} +25 -21
- package/src/Wallet/{Open.jsx → Open.tsx} +8 -11
- package/src/WalletOSIcon/{index.jsx → index.tsx} +8 -16
- package/src/WebWalletSWKeeper/{index.jsx → index.tsx} +21 -24
- package/src/WechatPrompt/{index.jsx → index.tsx} +1 -0
- package/src/global.d.ts +15 -0
- package/src/type.d.ts +12 -3
- package/src/withTheme/{index.jsx → index.tsx} +12 -2
- package/src/withTracker/{index.jsx → index.tsx} +6 -4
- package/src/Layout/dashboard/external-link.jsx +0 -47
- package/src/Logo/index.jsx +0 -66
- package/src/Result/index.jsx +0 -33
- package/src/SessionPermission/index.jsx +0 -28
- package/src/SessionUser/components/session-user-item.jsx +0 -93
- package/src/SessionUser/index.jsx +0 -38
- package/src/SessionUser/libs/utils.js +0 -37
- package/src/Spinner/index.jsx +0 -21
- /package/src/ErrorBoundary/{index.jsx → index.ts} +0 -0
- /package/src/NFTDisplay/{loading.jsx → loading.tsx} +0 -0
- /package/src/Passport/{index.jsx → index.ts} +0 -0
- /package/src/SessionManager/{index.jsx → index.tsx} +0 -0
@@ -1,12 +1,22 @@
|
|
1
|
-
/* eslint-disable react/no-array-index-key */
|
2
|
-
import PropTypes from 'prop-types';
|
3
1
|
import Typography from '@mui/material/Typography';
|
4
2
|
import { teal } from '@mui/material/colors';
|
5
3
|
import clsx from 'clsx';
|
6
4
|
import { styled } from '../../Theme';
|
7
5
|
import { NavLink } from './external-link';
|
8
6
|
|
9
|
-
|
7
|
+
export type LinkItem = {
|
8
|
+
url: string;
|
9
|
+
title: React.ReactNode;
|
10
|
+
icon?: React.ReactNode;
|
11
|
+
iconZoom?: number;
|
12
|
+
color?: string;
|
13
|
+
showBadge?: false | true;
|
14
|
+
external?: false | true;
|
15
|
+
active?: boolean;
|
16
|
+
children?: LinkItem[];
|
17
|
+
};
|
18
|
+
|
19
|
+
function renderItem(item: LinkItem, index: number) {
|
10
20
|
if (item.children?.length) {
|
11
21
|
// eslint-disable-next-line no-use-before-define
|
12
22
|
return renderGroup(item, index);
|
@@ -18,9 +28,7 @@ function renderItem(item, index) {
|
|
18
28
|
<NavLink
|
19
29
|
external={external}
|
20
30
|
to={url}
|
21
|
-
className={({
|
22
|
-
clsx('layout-sidebar-link', { 'layout-sidebar-link--active': external ? active : isActive })
|
23
|
-
}>
|
31
|
+
className={() => clsx('layout-sidebar-link', { 'layout-sidebar-link--active': external ? active : false })}>
|
24
32
|
{icon && <span className={`layout-sidebar-icon ${showBadge ? 'layout-sidebar-badge' : ''}`}>{icon}</span>}
|
25
33
|
<Typography component="span" className="layout-sidebar-link-text">
|
26
34
|
{title}
|
@@ -30,16 +38,22 @@ function renderItem(item, index) {
|
|
30
38
|
);
|
31
39
|
}
|
32
40
|
|
33
|
-
function renderGroup(item, index) {
|
41
|
+
function renderGroup(item: LinkItem, index: number) {
|
34
42
|
return (
|
35
43
|
<li key={`group-${item.title}-${index}`} className="layout-sidebar-group">
|
36
44
|
<span className="layout-sidebar-group-title">{item.title}</span>
|
37
|
-
<ul>{item.children
|
45
|
+
<ul>{item.children!.map(renderItem)}</ul>
|
38
46
|
</li>
|
39
47
|
);
|
40
48
|
}
|
41
49
|
|
42
|
-
|
50
|
+
export interface SidebarProps {
|
51
|
+
links: LinkItem[];
|
52
|
+
addons?: React.ReactNode;
|
53
|
+
dense?: false | true;
|
54
|
+
}
|
55
|
+
|
56
|
+
function Sidebar({ links, addons, dense = false, ...rest }: SidebarProps) {
|
43
57
|
return (
|
44
58
|
<Root {...rest} className={clsx({ 'layout-sidebar-dense': dense })}>
|
45
59
|
<ul>{links.map(renderItem)}</ul>
|
@@ -49,17 +63,6 @@ function Sidebar({ links, addons, dense, ...rest }) {
|
|
49
63
|
);
|
50
64
|
}
|
51
65
|
|
52
|
-
Sidebar.propTypes = {
|
53
|
-
links: PropTypes.array.isRequired,
|
54
|
-
addons: PropTypes.any,
|
55
|
-
dense: PropTypes.bool,
|
56
|
-
};
|
57
|
-
|
58
|
-
Sidebar.defaultProps = {
|
59
|
-
addons: null,
|
60
|
-
dense: false,
|
61
|
-
};
|
62
|
-
|
63
66
|
const gradient = 'linear-gradient(32deg, rgba(144, 255, 230, 0.1), rgba(144, 255, 230, 0))';
|
64
67
|
|
65
68
|
const Root = styled('div')`
|
@@ -1,6 +1,5 @@
|
|
1
|
-
import PropTypes from 'prop-types';
|
2
1
|
import Button from '@mui/material/IconButton';
|
3
|
-
import AppBar from '@mui/material/AppBar';
|
2
|
+
import AppBar, { type AppBarProps } from '@mui/material/AppBar';
|
4
3
|
import Toolbar from '@mui/material/Toolbar';
|
5
4
|
import Box from '@mui/material/Box';
|
6
5
|
import Typography from '@mui/material/Typography';
|
@@ -83,6 +82,16 @@ const StyledAppBar = styled(AppBar)`
|
|
83
82
|
}
|
84
83
|
`;
|
85
84
|
|
85
|
+
export interface HeaderProps extends AppBarProps {
|
86
|
+
onToggleMenu: () => void;
|
87
|
+
brand?: string;
|
88
|
+
description?: React.ReactNode;
|
89
|
+
addons?: React.ReactNode;
|
90
|
+
brandAddon?: React.ReactNode;
|
91
|
+
homeUrl?: string;
|
92
|
+
logo?: React.ReactNode;
|
93
|
+
}
|
94
|
+
|
86
95
|
/*
|
87
96
|
自定义 logo 相关:
|
88
97
|
如果为 logo prop 传入一个自定义的 svg, 并且 svg 中的元素通过 id 引用了 defs 中的元素 (比如 linearGradient),
|
@@ -93,16 +102,16 @@ const StyledAppBar = styled(AppBar)`
|
|
93
102
|
参考: https://blog.patw.me/archives/1820/inline-svg-same-id-and-display-none-issue/
|
94
103
|
*/
|
95
104
|
export default function Header({
|
96
|
-
|
105
|
+
onToggleMenu,
|
97
106
|
brand,
|
98
|
-
brandAddon,
|
99
107
|
description,
|
100
108
|
addons,
|
101
|
-
|
102
|
-
homeUrl,
|
109
|
+
brandAddon,
|
110
|
+
homeUrl = '/',
|
103
111
|
logo,
|
112
|
+
children,
|
104
113
|
...rest
|
105
|
-
}) {
|
114
|
+
}: HeaderProps) {
|
106
115
|
return (
|
107
116
|
<StyledAppBar position="sticky" className="header" {...rest}>
|
108
117
|
<Toolbar disableGutters={false} className="header-toolbar">
|
@@ -136,22 +145,3 @@ export default function Header({
|
|
136
145
|
</StyledAppBar>
|
137
146
|
);
|
138
147
|
}
|
139
|
-
|
140
|
-
Header.propTypes = {
|
141
|
-
onToggleMenu: PropTypes.func.isRequired,
|
142
|
-
brand: PropTypes.string.isRequired,
|
143
|
-
brandAddon: PropTypes.object,
|
144
|
-
description: PropTypes.any.isRequired,
|
145
|
-
children: PropTypes.any,
|
146
|
-
addons: PropTypes.any,
|
147
|
-
homeUrl: PropTypes.string,
|
148
|
-
logo: PropTypes.any,
|
149
|
-
};
|
150
|
-
|
151
|
-
Header.defaultProps = {
|
152
|
-
children: null,
|
153
|
-
addons: null,
|
154
|
-
brandAddon: null,
|
155
|
-
homeUrl: '/',
|
156
|
-
logo: null,
|
157
|
-
};
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import { useEffect, useState } from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
2
|
import Helmet from 'react-helmet';
|
4
3
|
import Container from '@mui/material/Container';
|
5
4
|
import Box from '@mui/material/Box';
|
6
|
-
import
|
5
|
+
import { type SxProps } from '@mui/material';
|
6
|
+
import Drawer, { type DrawerProps } from '@mui/material/Drawer';
|
7
7
|
import { useSize } from 'ahooks';
|
8
8
|
|
9
|
-
import Sidebar from './sidebar';
|
9
|
+
import Sidebar, { type LinkItem } from './sidebar';
|
10
10
|
import Header from './header';
|
11
11
|
import Footer from '../../Footer';
|
12
12
|
import { styled } from '../../Theme';
|
@@ -41,27 +41,43 @@ const Wrapper = styled('div')`
|
|
41
41
|
}
|
42
42
|
`;
|
43
43
|
|
44
|
+
export interface DashboardProps extends React.HTMLAttributes<HTMLDivElement> {
|
45
|
+
links?: LinkItem[];
|
46
|
+
brand?: string;
|
47
|
+
description?: React.ReactNode;
|
48
|
+
images: Record<string, string>;
|
49
|
+
title?: string;
|
50
|
+
brandAddon?: React.ReactNode;
|
51
|
+
headerAddon?: React.ReactNode;
|
52
|
+
prefix?: string;
|
53
|
+
fullWidth?: false | true;
|
54
|
+
contentLayout?: 'row' | 'column';
|
55
|
+
homeUrl?: string;
|
56
|
+
logo?: React.ReactNode;
|
57
|
+
sx?: SxProps;
|
58
|
+
}
|
59
|
+
|
44
60
|
export default function Dashboard({
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
61
|
+
links = [],
|
62
|
+
brand = '',
|
63
|
+
description = '',
|
64
|
+
images,
|
65
|
+
title = 'Home',
|
49
66
|
brandAddon,
|
50
67
|
headerAddon,
|
51
|
-
images,
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
className,
|
57
|
-
homeUrl,
|
68
|
+
prefix = '/images',
|
69
|
+
fullWidth = false,
|
70
|
+
contentLayout = 'column',
|
71
|
+
className = '',
|
72
|
+
homeUrl = '/',
|
58
73
|
logo,
|
74
|
+
children,
|
59
75
|
...rest
|
60
|
-
}) {
|
76
|
+
}: DashboardProps) {
|
61
77
|
const breakpoint = 960;
|
62
78
|
const size = useSize(document.body);
|
63
79
|
const width = size?.width || 0;
|
64
|
-
const [drawerMode, setDrawerMode] = useState(width >= breakpoint ? 'permanent' : 'temporary');
|
80
|
+
const [drawerMode, setDrawerMode] = useState<DrawerProps['variant']>(width >= breakpoint ? 'permanent' : 'temporary');
|
65
81
|
const [drawerOpen, setDrawerOpen] = useState(drawerMode === 'permanent');
|
66
82
|
|
67
83
|
useEffect(() => {
|
@@ -109,33 +125,3 @@ export default function Dashboard({
|
|
109
125
|
</Wrapper>
|
110
126
|
);
|
111
127
|
}
|
112
|
-
|
113
|
-
Dashboard.propTypes = {
|
114
|
-
children: PropTypes.any.isRequired,
|
115
|
-
title: PropTypes.string,
|
116
|
-
brand: PropTypes.string.isRequired,
|
117
|
-
links: PropTypes.array.isRequired,
|
118
|
-
images: PropTypes.object.isRequired,
|
119
|
-
brandAddon: PropTypes.object,
|
120
|
-
description: PropTypes.any.isRequired,
|
121
|
-
headerAddon: PropTypes.any,
|
122
|
-
prefix: PropTypes.string,
|
123
|
-
// 兼容旧版的设置,新版使用 fullWidth 进行设置
|
124
|
-
contentLayout: PropTypes.oneOf(['row', 'column']),
|
125
|
-
fullWidth: PropTypes.bool,
|
126
|
-
className: PropTypes.string,
|
127
|
-
homeUrl: PropTypes.string,
|
128
|
-
logo: PropTypes.any,
|
129
|
-
};
|
130
|
-
|
131
|
-
Dashboard.defaultProps = {
|
132
|
-
title: 'Home',
|
133
|
-
contentLayout: 'column',
|
134
|
-
headerAddon: null,
|
135
|
-
brandAddon: null,
|
136
|
-
prefix: '/images',
|
137
|
-
fullWidth: false,
|
138
|
-
className: '',
|
139
|
-
homeUrl: '/',
|
140
|
-
logo: null,
|
141
|
-
};
|
@@ -1,18 +1,36 @@
|
|
1
1
|
import { memo } from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
2
|
import { Link, useLocation } from 'react-router-dom';
|
4
|
-
import Button from '@mui/material/Button';
|
3
|
+
import Button, { type ButtonProps } from '@mui/material/Button';
|
5
4
|
import Typography from '@mui/material/Typography';
|
6
5
|
import { teal } from '@mui/material/colors';
|
6
|
+
import { type SxProps } from '@mui/material';
|
7
7
|
|
8
8
|
import ImageIcon from '../../Icon/image';
|
9
9
|
import Logo from '../../Logo';
|
10
10
|
import { styled, useTheme } from '../../Theme';
|
11
11
|
|
12
|
-
export
|
12
|
+
export type LinkItem = {
|
13
|
+
url: string;
|
14
|
+
title: React.ReactNode;
|
15
|
+
name: string;
|
16
|
+
showBadge?: false | true;
|
17
|
+
};
|
18
|
+
|
19
|
+
// const a: LinkItem = {};
|
20
|
+
|
21
|
+
export interface SidebarProps extends React.HTMLAttributes<HTMLDivElement> {
|
22
|
+
images: Record<string, string>;
|
23
|
+
links: LinkItem[];
|
24
|
+
prefix: string;
|
25
|
+
addons?: React.ReactNode;
|
26
|
+
logo?: React.ReactNode;
|
27
|
+
sx?: SxProps;
|
28
|
+
}
|
29
|
+
|
30
|
+
export default function Sidebar({ images, links, prefix = '/images', addons, logo, ...rest }: SidebarProps) {
|
13
31
|
const theme = useTheme();
|
14
32
|
const location = useLocation();
|
15
|
-
const isSelected = (
|
33
|
+
const isSelected = (_: string, name: string) => {
|
16
34
|
const pattern = new RegExp(`/${name}`);
|
17
35
|
return pattern.test(location.pathname);
|
18
36
|
};
|
@@ -45,20 +63,6 @@ export default function Sidebar({ images, links, prefix, addons, logo, ...rest }
|
|
45
63
|
);
|
46
64
|
}
|
47
65
|
|
48
|
-
Sidebar.propTypes = {
|
49
|
-
images: PropTypes.object.isRequired,
|
50
|
-
links: PropTypes.array.isRequired,
|
51
|
-
prefix: PropTypes.string,
|
52
|
-
addons: PropTypes.any,
|
53
|
-
logo: PropTypes.any,
|
54
|
-
};
|
55
|
-
|
56
|
-
Sidebar.defaultProps = {
|
57
|
-
prefix: '/images',
|
58
|
-
addons: null,
|
59
|
-
logo: null,
|
60
|
-
};
|
61
|
-
|
62
66
|
const MenuItems = memo(styled('div')`
|
63
67
|
flex: 1;
|
64
68
|
display: flex;
|
@@ -84,7 +88,11 @@ const MenuItems = memo(styled('div')`
|
|
84
88
|
|
85
89
|
const gradient = 'linear-gradient(32deg, rgba(144, 255, 230, 0.1), rgba(144, 255, 230, 0))';
|
86
90
|
|
87
|
-
|
91
|
+
type MenuItemProps = {
|
92
|
+
selected: boolean;
|
93
|
+
};
|
94
|
+
|
95
|
+
const MenuItem = styled(Button)<MenuItemProps & ButtonProps<typeof Link, { component: typeof Link }>>`
|
88
96
|
&& {
|
89
97
|
display: flex;
|
90
98
|
flex-direction: column;
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { useEffect, useState } from 'react';
|
2
|
-
import PropTypes from 'prop-types';
|
3
2
|
import Helmet from 'react-helmet';
|
4
3
|
import {
|
5
4
|
AppBar,
|
@@ -13,6 +12,7 @@ import {
|
|
13
12
|
ListItemText,
|
14
13
|
Toolbar,
|
15
14
|
Typography,
|
15
|
+
type SxProps,
|
16
16
|
} from '@mui/material';
|
17
17
|
import MenuIcon from '@mui/icons-material/Menu';
|
18
18
|
|
@@ -21,23 +21,44 @@ import OpenInWallet from '../Wallet/Open';
|
|
21
21
|
import Icon from '../Icon';
|
22
22
|
import Logo from '../Logo';
|
23
23
|
import { styled } from '../Theme';
|
24
|
+
import { type LinkItem } from './dashboard/sidebar';
|
25
|
+
|
26
|
+
export interface LayoutProps extends React.HTMLAttributes<HTMLDivElement> {
|
27
|
+
title: string;
|
28
|
+
brand: React.ReactNode;
|
29
|
+
description?: React.ReactNode;
|
30
|
+
links?: LinkItem[];
|
31
|
+
logo?: React.ReactNode;
|
32
|
+
showLogo?: false | true;
|
33
|
+
addons?: React.ReactNode;
|
34
|
+
footer?: React.ReactNode;
|
35
|
+
baseUrl?: string;
|
36
|
+
homeUrl?: string;
|
37
|
+
variant?: 'shadow' | 'border';
|
38
|
+
contentOnly?: false | true;
|
39
|
+
sx?: SxProps;
|
40
|
+
}
|
24
41
|
|
25
42
|
export default function Layout({
|
26
43
|
title,
|
27
44
|
brand,
|
28
45
|
description,
|
29
|
-
links,
|
30
|
-
logo,
|
31
|
-
showLogo,
|
46
|
+
links = [],
|
47
|
+
logo = <Logo showText={false} style={{ width: '40px', height: '40px' }} />,
|
48
|
+
showLogo = false,
|
32
49
|
addons,
|
33
|
-
footer
|
34
|
-
|
35
|
-
|
50
|
+
footer = (
|
51
|
+
<Container>
|
52
|
+
<Footer />
|
53
|
+
</Container>
|
54
|
+
),
|
55
|
+
baseUrl = '',
|
56
|
+
homeUrl = '/',
|
57
|
+
variant = 'shadow',
|
58
|
+
contentOnly = false,
|
36
59
|
children,
|
37
|
-
variant,
|
38
|
-
contentOnly,
|
39
60
|
...rest
|
40
|
-
}) {
|
61
|
+
}: LayoutProps) {
|
41
62
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
42
63
|
const onToggleDrawer = () => {
|
43
64
|
setDrawerOpen(!drawerOpen);
|
@@ -45,8 +66,9 @@ export default function Layout({
|
|
45
66
|
|
46
67
|
useEffect(() => {
|
47
68
|
const { searchParams } = new URL(window.location.href);
|
48
|
-
|
49
|
-
|
69
|
+
const inviter = searchParams.get('inviter');
|
70
|
+
if (inviter) {
|
71
|
+
window.localStorage.setItem('inviter', inviter);
|
50
72
|
}
|
51
73
|
}, []);
|
52
74
|
|
@@ -55,6 +77,7 @@ export default function Layout({
|
|
55
77
|
}
|
56
78
|
|
57
79
|
let activeLink = '';
|
80
|
+
// @ts-expect-error
|
58
81
|
const { pathname: currentPath } = new URL(window.location);
|
59
82
|
links.forEach((link) => {
|
60
83
|
if (currentPath.startsWith(link.url) && link.url.length > activeLink.length) {
|
@@ -74,8 +97,10 @@ export default function Layout({
|
|
74
97
|
<Link className="nav-link" key={x.url} href={x.url} underline="hover">
|
75
98
|
<ListItem button className={activeLink === x.url ? 'drawer-highlight-nav' : ''}>
|
76
99
|
<ListItemText>
|
77
|
-
{x.icon
|
100
|
+
{typeof x.icon === 'string' ? (
|
78
101
|
<Icon name={x.icon} size={18 * (x.iconZoom || 1)} color="inherit" style={{ marginRight: '5px' }} />
|
102
|
+
) : (
|
103
|
+
x.icon
|
79
104
|
)}
|
80
105
|
{x.title}
|
81
106
|
</ListItemText>
|
@@ -127,13 +152,15 @@ export default function Layout({
|
|
127
152
|
className={`nav-link ${activeLink === x.url ? 'highlight-nav' : ''}`}
|
128
153
|
color={x.color}
|
129
154
|
underline="hover">
|
130
|
-
{x.icon
|
155
|
+
{typeof x.icon === 'string' ? (
|
131
156
|
<Icon
|
132
157
|
name={x.icon}
|
133
158
|
size={20 * (x.iconZoom || 1)}
|
134
159
|
color="inherit"
|
135
160
|
style={{ marginRight: '5px' }}
|
136
161
|
/>
|
162
|
+
) : (
|
163
|
+
x.icon
|
137
164
|
)}
|
138
165
|
{x.title}
|
139
166
|
</Link>
|
@@ -167,39 +194,6 @@ export default function Layout({
|
|
167
194
|
);
|
168
195
|
}
|
169
196
|
|
170
|
-
Layout.propTypes = {
|
171
|
-
title: PropTypes.string.isRequired,
|
172
|
-
brand: PropTypes.any.isRequired,
|
173
|
-
description: PropTypes.any,
|
174
|
-
addons: PropTypes.any,
|
175
|
-
showLogo: PropTypes.bool,
|
176
|
-
logo: PropTypes.any,
|
177
|
-
links: PropTypes.array,
|
178
|
-
children: PropTypes.any.isRequired,
|
179
|
-
baseUrl: PropTypes.string,
|
180
|
-
homeUrl: PropTypes.string,
|
181
|
-
variant: PropTypes.oneOf(['shadow', 'border']),
|
182
|
-
footer: PropTypes.any,
|
183
|
-
contentOnly: PropTypes.bool,
|
184
|
-
};
|
185
|
-
|
186
|
-
Layout.defaultProps = {
|
187
|
-
contentOnly: false,
|
188
|
-
baseUrl: '',
|
189
|
-
homeUrl: '/',
|
190
|
-
links: [],
|
191
|
-
showLogo: false,
|
192
|
-
logo: <Logo showText={false} style={{ width: '40px', height: '40px' }} />,
|
193
|
-
variant: 'shadow',
|
194
|
-
addons: undefined,
|
195
|
-
description: undefined,
|
196
|
-
footer: (
|
197
|
-
<Container>
|
198
|
-
<Footer />
|
199
|
-
</Container>
|
200
|
-
),
|
201
|
-
};
|
202
|
-
|
203
197
|
const Div = styled('div')`
|
204
198
|
width: 100%;
|
205
199
|
min-height: 100vh;
|
@@ -1,13 +1,28 @@
|
|
1
|
-
import PropTypes from 'prop-types';
|
2
1
|
import { Box } from '@mui/material';
|
3
2
|
|
4
3
|
import { temp as colors } from '../Colors';
|
5
4
|
|
6
|
-
export
|
5
|
+
export interface LoadingMaskProps {
|
6
|
+
size?: number;
|
7
|
+
padding?: number;
|
8
|
+
borderWidth?: number;
|
9
|
+
borderRadius?: number;
|
10
|
+
duration?: number;
|
11
|
+
children?: React.ReactNode;
|
12
|
+
}
|
13
|
+
|
14
|
+
export default function LoadingMask({
|
15
|
+
size = 64,
|
16
|
+
padding,
|
17
|
+
borderWidth,
|
18
|
+
borderRadius,
|
19
|
+
duration,
|
20
|
+
children,
|
21
|
+
}: LoadingMaskProps) {
|
7
22
|
const finialSize = size;
|
8
23
|
const finialRadius = borderRadius ?? finialSize / 8;
|
9
24
|
const finialBorderWidth = borderWidth ?? finialSize / 32;
|
10
|
-
const finialPadding = padding ?? finialSize * 0.
|
25
|
+
const finialPadding = padding ?? finialSize * 0.25 - finialBorderWidth;
|
11
26
|
const finialDuration = duration ?? 2.5;
|
12
27
|
return (
|
13
28
|
<Box
|
@@ -81,20 +96,3 @@ export default function LoadingMask({ size, padding, borderWidth, borderRadius,
|
|
81
96
|
</Box>
|
82
97
|
);
|
83
98
|
}
|
84
|
-
|
85
|
-
LoadingMask.propTypes = {
|
86
|
-
size: PropTypes.number,
|
87
|
-
padding: PropTypes.number,
|
88
|
-
borderRadius: PropTypes.number,
|
89
|
-
borderWidth: PropTypes.number,
|
90
|
-
duration: PropTypes.number,
|
91
|
-
children: PropTypes.node.isRequired,
|
92
|
-
};
|
93
|
-
|
94
|
-
LoadingMask.defaultProps = {
|
95
|
-
size: 64,
|
96
|
-
padding: undefined,
|
97
|
-
borderWidth: undefined,
|
98
|
-
duration: undefined,
|
99
|
-
borderRadius: undefined,
|
100
|
-
};
|
@@ -1,7 +1,6 @@
|
|
1
1
|
/* eslint-disable no-param-reassign */
|
2
|
-
function startsWith(string, target, position) {
|
2
|
+
function startsWith(string: string, target: string, position: number = 0) {
|
3
3
|
const { length } = string;
|
4
|
-
position = position == null ? 0 : position;
|
5
4
|
if (position < 0) {
|
6
5
|
position = 0;
|
7
6
|
} else if (position > length) {
|
@@ -17,22 +16,25 @@ function getBrowserLang() {
|
|
17
16
|
return null;
|
18
17
|
}
|
19
18
|
|
20
|
-
const lang =
|
19
|
+
const lang: string =
|
21
20
|
(window.navigator.languages && window.navigator.languages[0]) ||
|
22
21
|
window.navigator.language ||
|
22
|
+
// @ts-expect-error
|
23
23
|
window.navigator.browserLanguage ||
|
24
|
+
// @ts-expect-error
|
24
25
|
window.navigator.userLanguage ||
|
26
|
+
// @ts-expect-error
|
25
27
|
window.navigator.systemLanguage ||
|
26
28
|
null;
|
27
29
|
|
28
30
|
return lang;
|
29
31
|
}
|
30
32
|
|
31
|
-
function normalizeCode(code) {
|
33
|
+
function normalizeCode(code?: string | null) {
|
32
34
|
return (code || '').toLowerCase().replace(/-/, '_');
|
33
35
|
}
|
34
36
|
|
35
|
-
function getPreferredLanguage(options) {
|
37
|
+
function getPreferredLanguage(options?: { languages?: string[]; fallback: string }) {
|
36
38
|
if (!options) {
|
37
39
|
return getBrowserLang();
|
38
40
|
}
|
@@ -49,14 +51,14 @@ function getPreferredLanguage(options) {
|
|
49
51
|
return fallback;
|
50
52
|
}
|
51
53
|
|
52
|
-
const match = languages
|
54
|
+
const match = languages!.filter((lang) => normalizeCode(lang) === browserLanguage);
|
53
55
|
|
54
56
|
if (match.length > 0) {
|
55
57
|
return match[0] || fallback;
|
56
58
|
}
|
57
59
|
|
58
60
|
// en == en_US
|
59
|
-
const matchCodeOnly = languages
|
61
|
+
const matchCodeOnly = languages!.filter((lang) => startsWith(browserLanguage, lang));
|
60
62
|
return matchCodeOnly[0] || fallback;
|
61
63
|
}
|
62
64
|
|
package/src/Locale/context.tsx
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* eslint-disable no-prototype-builtins */
|
2
|
-
import
|
2
|
+
import { createContext, useState, useEffect, useContext, useRef, useCallback, ReactNode } from 'react';
|
3
3
|
import get from 'lodash/get';
|
4
4
|
import Cookie from 'js-cookie';
|
5
5
|
|
@@ -7,6 +7,7 @@ import browserLang from './browser-lang';
|
|
7
7
|
import { translate } from './util';
|
8
8
|
|
9
9
|
import { getCookieOptions } from '../Util';
|
10
|
+
import type { Locale } from '../type';
|
10
11
|
|
11
12
|
const cookieName = 'nf_lang';
|
12
13
|
|
@@ -22,7 +23,7 @@ const getLocaleFromSearchParams = (
|
|
22
23
|
return null;
|
23
24
|
};
|
24
25
|
|
25
|
-
const setLocaleParam = (locale:
|
26
|
+
const setLocaleParam = (locale: Locale, url: string = window.location.href) => {
|
26
27
|
const urlObj = new URL(url);
|
27
28
|
const hasLocaleParam = urlObj.searchParams.has('locale');
|
28
29
|
if (hasLocaleParam) {
|
@@ -37,10 +38,10 @@ const getLocale = (languages: { code: string }[] = []): string => {
|
|
37
38
|
// 取 languages 首个元素的 code 值, 如果不存在则取 'en'
|
38
39
|
fallback: languages?.[0]?.code || 'en',
|
39
40
|
};
|
40
|
-
return getLocaleFromSearchParams(languages) || Cookie.get(cookieName) || browserLang(langParams)
|
41
|
+
return getLocaleFromSearchParams(languages) || Cookie.get(cookieName) || browserLang(langParams)!;
|
41
42
|
};
|
42
43
|
|
43
|
-
const setLocale = (locale:
|
44
|
+
const setLocale = (locale: Locale) => {
|
44
45
|
Cookie.set(cookieName, locale, getCookieOptions());
|
45
46
|
setLocaleParam(locale);
|
46
47
|
};
|
@@ -63,15 +64,21 @@ const getLanguages = (arg?: { code: string; name: string }[]): { code: string; n
|
|
63
64
|
|
64
65
|
interface LocaleProviderProps {
|
65
66
|
children: ReactNode;
|
66
|
-
locale?:
|
67
|
-
fallbackLocale?:
|
67
|
+
locale?: Locale;
|
68
|
+
fallbackLocale?: Locale;
|
68
69
|
translations: Record<string, any>;
|
69
|
-
|
70
|
-
onLoadingTranslation?: (locale: string, languages: { code: string }[]) => void;
|
70
|
+
onLoadingTranslation?: (locale: Locale, languages: { code: string }[]) => void;
|
71
71
|
languages?: { code: string; name: string }[];
|
72
72
|
}
|
73
73
|
|
74
|
-
|
74
|
+
export interface LocaleContextType {
|
75
|
+
locale: Locale;
|
76
|
+
changeLocale: (locale: Locale) => void;
|
77
|
+
t: (key: string, data?: Record<string, string>) => string;
|
78
|
+
languages: { code: string; name: string }[];
|
79
|
+
}
|
80
|
+
|
81
|
+
const LocaleContext = createContext<LocaleContextType>(null!);
|
75
82
|
const { Provider, Consumer } = LocaleContext;
|
76
83
|
|
77
84
|
function LocaleProvider({
|
@@ -85,11 +92,11 @@ function LocaleProvider({
|
|
85
92
|
}: LocaleProviderProps) {
|
86
93
|
const langs = getLanguages(languages);
|
87
94
|
// eslint-disable-next-line prefer-const
|
88
|
-
let [currentLocale, setCurrentLocale] = useState<
|
95
|
+
let [currentLocale, setCurrentLocale] = useState<Locale>(locale || getLocale(langs));
|
89
96
|
const lastCurrentLocale = useRef<string>(fallbackLocale || '');
|
90
97
|
const [, setForceUpdate] = useState(0);
|
91
98
|
|
92
|
-
const changeLocale = (newLocale:
|
99
|
+
const changeLocale = (newLocale: Locale) => {
|
93
100
|
setCurrentLocale(newLocale);
|
94
101
|
setLocale(newLocale);
|
95
102
|
};
|