@arcblock/ux 2.10.38 → 2.10.40
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/BlockletV2/blocklet.d.ts +2 -1
- package/lib/BlockletV2/blocklet.js +55 -59
- package/lib/BlockletV2/components/icon-text.js +1 -1
- package/lib/Locale/context.d.ts +22 -38
- package/lib/Locale/context.js +5 -24
- package/package.json +6 -5
- package/src/BlockletV2/blocklet.tsx +39 -35
- package/src/BlockletV2/components/icon-text.tsx +1 -1
- package/src/Locale/{context.jsx → context.tsx} +35 -31
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
import { CardProps } from '@mui/material';
|
|
3
|
+
export interface IBlockletStore extends CardProps {
|
|
3
4
|
did?: string;
|
|
4
5
|
title: string;
|
|
5
6
|
description?: string;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React, { isValidElement } from 'react';
|
|
3
3
|
import Download from '@iconify-icons/tabler/cloud-download';
|
|
4
4
|
import { Icon } from '@iconify/react';
|
|
5
|
-
import { Card,
|
|
5
|
+
import { Card, CircularProgress, Stack, Typography } from '@mui/material';
|
|
6
6
|
import Avatar from '../Avatar';
|
|
7
7
|
import Button from '../Button';
|
|
8
8
|
import { useTheme } from '../Theme';
|
|
@@ -61,67 +61,65 @@ export default function BlockletStore(props) {
|
|
|
61
61
|
};
|
|
62
62
|
return /*#__PURE__*/_jsxs(Card, {
|
|
63
63
|
variant: "outlined",
|
|
64
|
-
sx: {
|
|
65
|
-
borderRadius: 2
|
|
66
|
-
},
|
|
67
64
|
onClick: handleMainClick,
|
|
68
65
|
...rest,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
sx: {
|
|
67
|
+
p: {
|
|
68
|
+
xs: 2,
|
|
69
|
+
md: 3
|
|
73
70
|
},
|
|
74
|
-
|
|
71
|
+
borderRadius: 2,
|
|
72
|
+
...rest.sx
|
|
73
|
+
},
|
|
74
|
+
children: [/*#__PURE__*/_jsxs(Stack, {
|
|
75
|
+
flex: 1,
|
|
76
|
+
direction: "row",
|
|
77
|
+
gap: 2,
|
|
78
|
+
alignItems: "center",
|
|
79
|
+
overflow: "hidden",
|
|
80
|
+
children: [/*#__PURE__*/_jsx(Avatar, {
|
|
81
|
+
src: cover,
|
|
82
|
+
did: did,
|
|
83
|
+
size: 48,
|
|
84
|
+
variant: "rounded"
|
|
85
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
75
86
|
flex: 1,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
size: "small",
|
|
99
|
-
disabled: buttonDisabled || buttonLoading,
|
|
87
|
+
fontWeight: "typography.fontWeightMedium",
|
|
88
|
+
sx: {
|
|
89
|
+
fontSize: 16,
|
|
90
|
+
textOverflow: 'ellipsis',
|
|
91
|
+
whiteSpace: 'nowrap',
|
|
92
|
+
overflow: 'hidden'
|
|
93
|
+
},
|
|
94
|
+
...titleProps
|
|
95
|
+
}), button || onButtonClick && /*#__PURE__*/_jsxs(Button, {
|
|
96
|
+
color: "reverse",
|
|
97
|
+
variant: "outlined",
|
|
98
|
+
size: "small",
|
|
99
|
+
disabled: buttonDisabled || buttonLoading,
|
|
100
|
+
style: {
|
|
101
|
+
borderColor: theme.palette.grey[300],
|
|
102
|
+
borderRadius: 8,
|
|
103
|
+
fontSize: 13,
|
|
104
|
+
fontWeight: theme.typography.fontWeightMedium
|
|
105
|
+
},
|
|
106
|
+
onClick: handleButtonClick,
|
|
107
|
+
children: [buttonLoading && /*#__PURE__*/_jsx(CircularProgress, {
|
|
108
|
+
size: 15,
|
|
100
109
|
style: {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
marginRight: 3,
|
|
109
|
-
color: 'inherit'
|
|
110
|
-
}
|
|
111
|
-
}), buttonText]
|
|
112
|
-
})]
|
|
113
|
-
})
|
|
114
|
-
}), /*#__PURE__*/_jsx(CardContent, {
|
|
115
|
-
sx: {
|
|
116
|
-
py: 0
|
|
117
|
-
},
|
|
110
|
+
marginRight: 3,
|
|
111
|
+
color: 'inherit'
|
|
112
|
+
}
|
|
113
|
+
}), buttonText]
|
|
114
|
+
})]
|
|
115
|
+
}), /*#__PURE__*/_jsx(Stack, {
|
|
116
|
+
py: 2,
|
|
118
117
|
children: /*#__PURE__*/_jsx(Typography, {
|
|
119
|
-
component: "div",
|
|
120
118
|
variant: "body2",
|
|
121
119
|
color: "text.secondary",
|
|
122
120
|
sx: {
|
|
123
|
-
lineClamp: 2,
|
|
124
121
|
display: '-webkit-box',
|
|
122
|
+
lineClamp: 2,
|
|
125
123
|
WebkitLineClamp: 2,
|
|
126
124
|
WebkitBoxOrient: 'vertical',
|
|
127
125
|
overflow: 'hidden',
|
|
@@ -129,13 +127,11 @@ export default function BlockletStore(props) {
|
|
|
129
127
|
},
|
|
130
128
|
...descriptionProps
|
|
131
129
|
})
|
|
132
|
-
}), /*#__PURE__*/_jsxs(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
color: 'grey.800'
|
|
138
|
-
},
|
|
130
|
+
}), /*#__PURE__*/_jsxs(Stack, {
|
|
131
|
+
direction: "row",
|
|
132
|
+
alignItems: "center",
|
|
133
|
+
gap: 2,
|
|
134
|
+
color: "text.secondary",
|
|
139
135
|
children: [/*#__PURE__*/_jsx(IconText, {
|
|
140
136
|
icon: /*#__PURE__*/_jsx(Avatar, {
|
|
141
137
|
src: avatar,
|
package/lib/Locale/context.d.ts
CHANGED
|
@@ -1,39 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
code: PropTypes.Requireable<string>;
|
|
19
|
-
name: PropTypes.Requireable<string>;
|
|
20
|
-
}> | null | undefined)[]>;
|
|
21
|
-
}
|
|
22
|
-
namespace defaultProps {
|
|
23
|
-
let locale_1: string;
|
|
24
|
-
export { locale_1 as locale };
|
|
25
|
-
let fallbackLocale_1: string;
|
|
26
|
-
export { fallbackLocale_1 as fallbackLocale };
|
|
27
|
-
let languages_1: never[];
|
|
28
|
-
export { languages_1 as languages };
|
|
29
|
-
export function onLoadingTranslation_1(): void;
|
|
30
|
-
export { onLoadingTranslation_1 as onLoadingTranslation };
|
|
31
|
-
}
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
declare const getLocale: (languages?: {
|
|
3
|
+
code: string;
|
|
4
|
+
}[]) => string;
|
|
5
|
+
declare const setLocale: (locale: string) => void;
|
|
6
|
+
interface LocaleProviderProps {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
locale?: string;
|
|
9
|
+
fallbackLocale?: string;
|
|
10
|
+
translations: Record<string, any>;
|
|
11
|
+
onLoadingTranslation?: (locale: string, languages: {
|
|
12
|
+
code: string;
|
|
13
|
+
}[]) => void;
|
|
14
|
+
languages?: {
|
|
15
|
+
code: string;
|
|
16
|
+
name: string;
|
|
17
|
+
}[];
|
|
32
18
|
}
|
|
33
|
-
declare const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export
|
|
38
|
-
import PropTypes from 'prop-types';
|
|
39
|
-
export { Consumer as LocaleConsumer };
|
|
19
|
+
declare const LocaleContext: React.Context<any>;
|
|
20
|
+
declare const Consumer: React.Consumer<any>;
|
|
21
|
+
declare function LocaleProvider({ children, locale, fallbackLocale, translations, onLoadingTranslation, languages, ...rest }: LocaleProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
declare function useLocaleContext(): any;
|
|
23
|
+
export { LocaleProvider, Consumer as LocaleConsumer, LocaleContext, useLocaleContext, setLocale, getLocale };
|
package/lib/Locale/context.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable no-prototype-builtins */
|
|
3
|
-
import { createContext, useState, useEffect, useContext, useRef, useCallback } from 'react';
|
|
3
|
+
import React, { createContext, useState, useEffect, useContext, useRef, useCallback } from 'react';
|
|
4
4
|
import get from 'lodash/get';
|
|
5
|
-
import PropTypes from 'prop-types';
|
|
6
5
|
import Cookie from 'js-cookie';
|
|
7
6
|
import browserLang from './browser-lang';
|
|
8
7
|
import { translate } from './util';
|
|
@@ -53,7 +52,7 @@ const getLanguages = arg => {
|
|
|
53
52
|
name: '简体中文'
|
|
54
53
|
}];
|
|
55
54
|
};
|
|
56
|
-
const LocaleContext = /*#__PURE__*/createContext();
|
|
55
|
+
const LocaleContext = /*#__PURE__*/createContext(null);
|
|
57
56
|
const {
|
|
58
57
|
Provider,
|
|
59
58
|
Consumer
|
|
@@ -64,13 +63,13 @@ function LocaleProvider({
|
|
|
64
63
|
fallbackLocale,
|
|
65
64
|
translations,
|
|
66
65
|
onLoadingTranslation,
|
|
67
|
-
languages,
|
|
66
|
+
languages = [],
|
|
68
67
|
...rest
|
|
69
68
|
}) {
|
|
70
69
|
const langs = getLanguages(languages);
|
|
71
70
|
// eslint-disable-next-line prefer-const
|
|
72
71
|
let [currentLocale, setCurrentLocale] = useState(locale || getLocale(langs));
|
|
73
|
-
const lastCurrentLocale = useRef(fallbackLocale);
|
|
72
|
+
const lastCurrentLocale = useRef(fallbackLocale || '');
|
|
74
73
|
const [, setForceUpdate] = useState(0);
|
|
75
74
|
const changeLocale = newLocale => {
|
|
76
75
|
setCurrentLocale(newLocale);
|
|
@@ -97,7 +96,7 @@ function LocaleProvider({
|
|
|
97
96
|
} catch (err) {
|
|
98
97
|
console.error(err);
|
|
99
98
|
}
|
|
100
|
-
onLoadingTranslation(tmpLocale, langs);
|
|
99
|
+
onLoadingTranslation?.(tmpLocale, langs);
|
|
101
100
|
currentLocale = lastCurrentLocale.current;
|
|
102
101
|
} else {
|
|
103
102
|
lastCurrentLocale.current = currentLocale;
|
|
@@ -118,22 +117,4 @@ function useLocaleContext() {
|
|
|
118
117
|
const context = useContext(LocaleContext);
|
|
119
118
|
return context;
|
|
120
119
|
}
|
|
121
|
-
LocaleProvider.propTypes = {
|
|
122
|
-
children: PropTypes.any.isRequired,
|
|
123
|
-
translations: PropTypes.object.isRequired,
|
|
124
|
-
onLoadingTranslation: PropTypes.func,
|
|
125
|
-
locale: PropTypes.string,
|
|
126
|
-
// 会影响 translate(key) 的结果 - 当 key 无效时查找 fallbackLocale 对应的翻译结果
|
|
127
|
-
fallbackLocale: PropTypes.string,
|
|
128
|
-
languages: PropTypes.arrayOf(PropTypes.shape({
|
|
129
|
-
code: PropTypes.string,
|
|
130
|
-
name: PropTypes.string
|
|
131
|
-
}))
|
|
132
|
-
};
|
|
133
|
-
LocaleProvider.defaultProps = {
|
|
134
|
-
locale: '',
|
|
135
|
-
fallbackLocale: '',
|
|
136
|
-
languages: [],
|
|
137
|
-
onLoadingTranslation: () => {}
|
|
138
|
-
};
|
|
139
120
|
export { LocaleProvider, Consumer as LocaleConsumer, LocaleContext, useLocaleContext, setLocale, getLocale };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/ux",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.40",
|
|
4
4
|
"description": "Common used react components for arcblock products",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"jest": "^29.7.0",
|
|
54
54
|
"jest-environment-jsdom": "^29.7.0",
|
|
55
55
|
"moment-timezone": "^0.5.37",
|
|
56
|
+
"prettier": "^3.3.3",
|
|
56
57
|
"typescript": "5.5.4"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
@@ -63,12 +64,12 @@
|
|
|
63
64
|
"react": ">=18.2.0",
|
|
64
65
|
"react-router-dom": ">=6.22.3"
|
|
65
66
|
},
|
|
66
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "cad80dfa31fd28039f02bc14379a19a254a36000",
|
|
67
68
|
"dependencies": {
|
|
68
69
|
"@arcblock/did-motif": "^1.1.13",
|
|
69
|
-
"@arcblock/icons": "^2.10.
|
|
70
|
-
"@arcblock/nft-display": "^2.10.
|
|
71
|
-
"@arcblock/react-hooks": "^2.10.
|
|
70
|
+
"@arcblock/icons": "^2.10.40",
|
|
71
|
+
"@arcblock/nft-display": "^2.10.40",
|
|
72
|
+
"@arcblock/react-hooks": "^2.10.40",
|
|
72
73
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
73
74
|
"@fontsource/inter": "^5.0.16",
|
|
74
75
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
|
@@ -2,15 +2,14 @@ import React, { isValidElement } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import Download from '@iconify-icons/tabler/cloud-download';
|
|
4
4
|
import { Icon } from '@iconify/react';
|
|
5
|
-
import { Card,
|
|
5
|
+
import { Card, CardProps, CircularProgress, Stack, Typography } from '@mui/material';
|
|
6
6
|
import Avatar from '../Avatar';
|
|
7
7
|
import Button from '../Button';
|
|
8
8
|
import { useTheme } from '../Theme';
|
|
9
9
|
import IconText from './components/icon-text';
|
|
10
10
|
import { formatDownloadCount, strippedString } from './utils';
|
|
11
11
|
|
|
12
|
-
export interface IBlockletStore
|
|
13
|
-
extends Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, 'title' | 'className'> {
|
|
12
|
+
export interface IBlockletStore extends CardProps {
|
|
14
13
|
did?: string;
|
|
15
14
|
title: string;
|
|
16
15
|
description?: string;
|
|
@@ -77,40 +76,45 @@ export default function BlockletStore(props: IBlockletStore) {
|
|
|
77
76
|
: { title: strippedString(description), dangerouslySetInnerHTML: { __html: description } };
|
|
78
77
|
|
|
79
78
|
return (
|
|
80
|
-
<Card
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
79
|
+
<Card
|
|
80
|
+
variant="outlined"
|
|
81
|
+
onClick={handleMainClick}
|
|
82
|
+
{...rest}
|
|
83
|
+
sx={{ p: { xs: 2, md: 3 }, borderRadius: 2, ...rest.sx }}>
|
|
84
|
+
<Stack flex={1} direction="row" gap={2} alignItems="center" overflow="hidden">
|
|
85
|
+
<Avatar src={cover} did={did} size={48} variant="rounded" />
|
|
86
|
+
<Typography
|
|
87
|
+
flex={1}
|
|
88
|
+
fontWeight="typography.fontWeightMedium"
|
|
89
|
+
sx={{ fontSize: 16, textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }}
|
|
90
|
+
{...titleProps}
|
|
91
|
+
/>
|
|
92
|
+
{button ||
|
|
93
|
+
(onButtonClick && (
|
|
94
|
+
<Button
|
|
95
|
+
color="reverse"
|
|
96
|
+
variant="outlined"
|
|
97
|
+
size="small"
|
|
98
|
+
disabled={buttonDisabled || buttonLoading}
|
|
99
|
+
style={{
|
|
100
|
+
borderColor: theme.palette.grey[300],
|
|
101
|
+
borderRadius: 8,
|
|
102
|
+
fontSize: 13,
|
|
103
|
+
fontWeight: theme.typography.fontWeightMedium,
|
|
104
|
+
}}
|
|
105
|
+
onClick={handleButtonClick}>
|
|
106
|
+
{buttonLoading && <CircularProgress size={15} style={{ marginRight: 3, color: 'inherit' }} />}
|
|
107
|
+
{buttonText}
|
|
108
|
+
</Button>
|
|
109
|
+
))}
|
|
110
|
+
</Stack>
|
|
111
|
+
<Stack py={2}>
|
|
107
112
|
<Typography
|
|
108
|
-
component="div"
|
|
109
113
|
variant="body2"
|
|
110
114
|
color="text.secondary"
|
|
111
115
|
sx={{
|
|
112
|
-
lineClamp: 2,
|
|
113
116
|
display: '-webkit-box',
|
|
117
|
+
lineClamp: 2,
|
|
114
118
|
WebkitLineClamp: 2,
|
|
115
119
|
WebkitBoxOrient: 'vertical',
|
|
116
120
|
overflow: 'hidden',
|
|
@@ -118,13 +122,13 @@ export default function BlockletStore(props: IBlockletStore) {
|
|
|
118
122
|
}}
|
|
119
123
|
{...descriptionProps}
|
|
120
124
|
/>
|
|
121
|
-
</
|
|
122
|
-
<
|
|
125
|
+
</Stack>
|
|
126
|
+
<Stack direction="row" alignItems="center" gap={2} color="text.secondary">
|
|
123
127
|
<IconText icon={<Avatar src={avatar} did={did} size={20} variant="circle" />}>{author}</IconText>
|
|
124
128
|
<IconText icon={<Icon icon={Download} />} title={download}>
|
|
125
129
|
{formatDownloadCount(download)}
|
|
126
130
|
</IconText>
|
|
127
|
-
</
|
|
131
|
+
</Stack>
|
|
128
132
|
</Card>
|
|
129
133
|
);
|
|
130
134
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-prototype-builtins */
|
|
2
|
-
import { createContext, useState, useEffect, useContext, useRef, useCallback } from 'react';
|
|
2
|
+
import React, { createContext, useState, useEffect, useContext, useRef, useCallback, ReactNode } from 'react';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
4
|
import Cookie from 'js-cookie';
|
|
6
5
|
|
|
7
6
|
import browserLang from './browser-lang';
|
|
@@ -12,7 +11,10 @@ import { getCookieOptions } from '../Util';
|
|
|
12
11
|
const cookieName = 'nf_lang';
|
|
13
12
|
|
|
14
13
|
// 跨应用传递多语言选择的方式是在 query string 中添加 locale 参数,LocaleSelector 要高优先级遵守这个参数
|
|
15
|
-
const getLocaleFromSearchParams = (
|
|
14
|
+
const getLocaleFromSearchParams = (
|
|
15
|
+
languages: { code: string }[],
|
|
16
|
+
url: string = window.location.href
|
|
17
|
+
): string | null => {
|
|
16
18
|
const locale = new URL(url).searchParams.get('locale');
|
|
17
19
|
if (languages.find((x) => x.code === locale)) {
|
|
18
20
|
return locale;
|
|
@@ -20,7 +22,7 @@ const getLocaleFromSearchParams = (languages, url = window.location.href) => {
|
|
|
20
22
|
return null;
|
|
21
23
|
};
|
|
22
24
|
|
|
23
|
-
const setLocaleParam = (locale, url = window.location.href) => {
|
|
25
|
+
const setLocaleParam = (locale: string, url: string = window.location.href) => {
|
|
24
26
|
const urlObj = new URL(url);
|
|
25
27
|
const hasLocaleParam = urlObj.searchParams.has('locale');
|
|
26
28
|
if (hasLocaleParam) {
|
|
@@ -29,7 +31,7 @@ const setLocaleParam = (locale, url = window.location.href) => {
|
|
|
29
31
|
}
|
|
30
32
|
};
|
|
31
33
|
|
|
32
|
-
const getLocale = (languages = []) => {
|
|
34
|
+
const getLocale = (languages: { code: string }[] = []): string => {
|
|
33
35
|
const langParams = {
|
|
34
36
|
languages: languages.map((item) => item.code),
|
|
35
37
|
// 取 languages 首个元素的 code 值, 如果不存在则取 'en'
|
|
@@ -38,12 +40,12 @@ const getLocale = (languages = []) => {
|
|
|
38
40
|
return getLocaleFromSearchParams(languages) || Cookie.get(cookieName) || browserLang(langParams);
|
|
39
41
|
};
|
|
40
42
|
|
|
41
|
-
const setLocale = (locale) => {
|
|
43
|
+
const setLocale = (locale: string) => {
|
|
42
44
|
Cookie.set(cookieName, locale, getCookieOptions());
|
|
43
45
|
setLocaleParam(locale);
|
|
44
46
|
};
|
|
45
47
|
|
|
46
|
-
const getLanguages = (arg) => {
|
|
48
|
+
const getLanguages = (arg?: { code: string; name: string }[]): { code: string; name: string }[] => {
|
|
47
49
|
const env = get(window, 'blocklet.languages');
|
|
48
50
|
if (Array.isArray(env) && env.length) {
|
|
49
51
|
return env;
|
|
@@ -59,16 +61,35 @@ const getLanguages = (arg) => {
|
|
|
59
61
|
];
|
|
60
62
|
};
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
interface LocaleProviderProps {
|
|
65
|
+
children: ReactNode;
|
|
66
|
+
locale?: string;
|
|
67
|
+
fallbackLocale?: string;
|
|
68
|
+
translations: Record<string, any>;
|
|
69
|
+
// eslint-disable-next-line no-unused-vars
|
|
70
|
+
onLoadingTranslation?: (locale: string, languages: { code: string }[]) => void;
|
|
71
|
+
languages?: { code: string; name: string }[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const LocaleContext = createContext<any>(null);
|
|
63
75
|
const { Provider, Consumer } = LocaleContext;
|
|
64
|
-
|
|
76
|
+
|
|
77
|
+
function LocaleProvider({
|
|
78
|
+
children,
|
|
79
|
+
locale,
|
|
80
|
+
fallbackLocale,
|
|
81
|
+
translations,
|
|
82
|
+
onLoadingTranslation,
|
|
83
|
+
languages = [],
|
|
84
|
+
...rest
|
|
85
|
+
}: LocaleProviderProps) {
|
|
65
86
|
const langs = getLanguages(languages);
|
|
66
87
|
// eslint-disable-next-line prefer-const
|
|
67
|
-
let [currentLocale, setCurrentLocale] = useState(locale || getLocale(langs));
|
|
68
|
-
const lastCurrentLocale = useRef(fallbackLocale);
|
|
88
|
+
let [currentLocale, setCurrentLocale] = useState<string>(locale || getLocale(langs));
|
|
89
|
+
const lastCurrentLocale = useRef<string>(fallbackLocale || '');
|
|
69
90
|
const [, setForceUpdate] = useState(0);
|
|
70
91
|
|
|
71
|
-
const changeLocale = (newLocale) => {
|
|
92
|
+
const changeLocale = (newLocale: string) => {
|
|
72
93
|
setCurrentLocale(newLocale);
|
|
73
94
|
setLocale(newLocale);
|
|
74
95
|
};
|
|
@@ -95,14 +116,14 @@ function LocaleProvider({ children, locale, fallbackLocale, translations, onLoad
|
|
|
95
116
|
console.error(err);
|
|
96
117
|
}
|
|
97
118
|
|
|
98
|
-
onLoadingTranslation(tmpLocale, langs);
|
|
119
|
+
onLoadingTranslation?.(tmpLocale, langs);
|
|
99
120
|
currentLocale = lastCurrentLocale.current;
|
|
100
121
|
} else {
|
|
101
122
|
lastCurrentLocale.current = currentLocale;
|
|
102
123
|
}
|
|
103
124
|
|
|
104
125
|
const t = useCallback(
|
|
105
|
-
(key, data) => translate(translations, key, currentLocale, fallbackLocale, data),
|
|
126
|
+
(key: string, data?: any) => translate(translations, key, currentLocale, fallbackLocale, data),
|
|
106
127
|
[translations, currentLocale, fallbackLocale]
|
|
107
128
|
);
|
|
108
129
|
|
|
@@ -114,21 +135,4 @@ function useLocaleContext() {
|
|
|
114
135
|
return context;
|
|
115
136
|
}
|
|
116
137
|
|
|
117
|
-
LocaleProvider.propTypes = {
|
|
118
|
-
children: PropTypes.any.isRequired,
|
|
119
|
-
translations: PropTypes.object.isRequired,
|
|
120
|
-
onLoadingTranslation: PropTypes.func,
|
|
121
|
-
locale: PropTypes.string,
|
|
122
|
-
// 会影响 translate(key) 的结果 - 当 key 无效时查找 fallbackLocale 对应的翻译结果
|
|
123
|
-
fallbackLocale: PropTypes.string,
|
|
124
|
-
languages: PropTypes.arrayOf(PropTypes.shape({ code: PropTypes.string, name: PropTypes.string })),
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
LocaleProvider.defaultProps = {
|
|
128
|
-
locale: '',
|
|
129
|
-
fallbackLocale: '',
|
|
130
|
-
languages: [],
|
|
131
|
-
onLoadingTranslation: () => {},
|
|
132
|
-
};
|
|
133
|
-
|
|
134
138
|
export { LocaleProvider, Consumer as LocaleConsumer, LocaleContext, useLocaleContext, setLocale, getLocale };
|